diff options
24 files changed, 5165 insertions, 98 deletions
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt index 4207b1f0615a..0c2e365cd099 100644 --- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt @@ -359,7 +359,7 @@ First Level Node - FG Gen3 device Value type: <u32> Definition: Value in micro percentage for low temperature ESR tight filter. If this is not specified, then a default value of - 48829 (4.88 %) will be used. Lowest possible value is 1954 + 30000 (3 %) will be used. Lowest possible value is 1954 (0.19 %). - qcom,fg-esr-broad-lt-filter-micro-pct @@ -367,7 +367,7 @@ First Level Node - FG Gen3 device Value type: <u32> Definition: Value in micro percentage for low temperature ESR broad filter. If this is not specified, then a default value of - 148438 (14.84 %) will be used. Lowest possible value is + 30000 (3 %) will be used. Lowest possible value is 1954 (0.19 %). - qcom,fg-auto-recharge-soc diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index 7820562d17ae..b6d0c9affa0e 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -1408,6 +1408,8 @@ Optional properties: - qcom,wsa-max-devs : Maximum number of WSA881x devices present in the target - qcom,wsa-devs : List of phandles for all possible WSA881x devices supported for the target - qcom,wsa-aux-dev-prefix : Name prefix with Left/Right configuration for WSA881x device +- qcom,tdm-audio-intf : Boolean. This property is used to specify whether TDM interface + is supported or not to the machine driver. Example: diff --git a/arch/arm/boot/dts/qcom/msm-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi index 75aea7280e6c..4b37032e1775 100644 --- a/arch/arm/boot/dts/qcom/msm-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi @@ -833,6 +833,8 @@ "RX_BIAS", "INT_MCLK0", "SPK_RX_BIAS", "INT_MCLK0", "INT_LDO_H", "INT_MCLK0", + "RX_I2S_CLK", "INT_MCLK0", + "TX_I2S_CLK", "INT_MCLK0", "MIC BIAS External", "Handset Mic", "MIC BIAS External2", "Headset Mic", "MIC BIAS External", "Secondary Mic", diff --git a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi index 0bd9b02f3d2e..24f593aa5e9f 100644 --- a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi @@ -726,6 +726,7 @@ sound-9335 { qcom,model = "msm8996-tasha-mtp-snd-card"; + qcom,tdm-audio-intf; qcom,audio-routing = "AIF4 VI", "MCLK", @@ -760,6 +761,66 @@ asoc-codec = <&stub_codec>, <&hdmi_audio>; asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-audio-codec-rx"; + asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, + <&dai_hdmi>, <&dai_mi2s>, + <&sb_0_rx>, <&sb_0_tx>, + <&sb_1_rx>, <&sb_1_tx>, + <&sb_2_rx>, <&sb_2_tx>, + <&sb_3_rx>, <&sb_3_tx>, + <&sb_4_rx>, <&sb_4_tx>, + <&sb_5_tx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, + <&afe_proxy_rx>, <&afe_proxy_tx>, + <&incall_record_rx>, <&incall_record_tx>, + <&incall_music_rx>, <&incall_music2_rx>, + <&sb_5_rx>, <&sb_6_rx>, + <&usb_audio_rx>, <&usb_audio_tx>, + <&dai_pri_tdm_tx_0>, <&dai_pri_tdm_tx_1>, + <&dai_pri_tdm_tx_2>, <&dai_pri_tdm_tx_3>, + <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_rx_1>, + <&dai_pri_tdm_rx_2>, <&dai_pri_tdm_rx_3>, + <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_rx_1>, + <&dai_sec_tdm_rx_2>, <&dai_sec_tdm_rx_3>, + <&dai_sec_tdm_tx_0>, <&dai_sec_tdm_tx_1>, + <&dai_sec_tdm_tx_2>, <&dai_sec_tdm_tx_3>, + <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_rx_1>, + <&dai_tert_tdm_rx_2>, <&dai_tert_tdm_rx_3>, + <&dai_tert_tdm_tx_0>, <&dai_tert_tdm_tx_1>, + <&dai_tert_tdm_tx_2>, <&dai_tert_tdm_tx_3>, + <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_rx_1>, + <&dai_quat_tdm_rx_2>, <&dai_quat_tdm_rx_3>, + <&dai_quat_tdm_tx_0>, <&dai_quat_tdm_tx_1>, + <&dai_quat_tdm_tx_2>, <&dai_quat_tdm_tx_3>; + asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", + "msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.2", + "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.16395", + "msm-dai-q6-dev.224", "msm-dai-q6-dev.225", + "msm-dai-q6-dev.241", "msm-dai-q6-dev.240", + "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772", + "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770", + "msm-dai-q6-dev.16394", "msm-dai-q6-dev.16396", + "msm-dai-q6-dev.28672", "msm-dai-q6-dev.28673", + "msm-dai-q6-tdm.36865", "msm-dai-q6-tdm.36867", + "msm-dai-q6-tdm.36869", "msm-dai-q6-tdm.36871", + "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36866", + "msm-dai-q6-tdm.36868", "msm-dai-q6-tdm.36870", + "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36882", + "msm-dai-q6-tdm.36884", "msm-dai-q6-tdm.36886", + "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36883", + "msm-dai-q6-tdm.36885", "msm-dai-q6-tdm.36887", + "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36898", + "msm-dai-q6-tdm.36900", "msm-dai-q6-tdm.36902", + "msm-dai-q6-tdm.36897", "msm-dai-q6-tdm.36899", + "msm-dai-q6-tdm.36901", "msm-dai-q6-tdm.36903", + "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36914", + "msm-dai-q6-tdm.36916", "msm-dai-q6-tdm.36918", + "msm-dai-q6-tdm.36913", "msm-dai-q6-tdm.36915", + "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919"; qcom,hph-en1-gpio = <&pmi8994_gpios 10 0>; qcom,hph-en0-gpio = <&pm8994_gpios 13 0>; qcom,us-euro-gpios = <&pm8994_mpps 2 0>; @@ -769,6 +830,35 @@ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", "SpkrLeft", "SpkrRight"; }; + qcom,msm-dai-tdm-tert-rx { + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <0>; + qcom,msm-cpudai-tdm-sync-src = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&tert_tdm_dout_active>; + pinctrl-1 = <&tert_tdm_dout_sleep>; + }; + qcom,msm-dai-tdm-tert-tx { + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <0>; + qcom,msm-cpudai-tdm-sync-src = <1>; + }; + qcom,msm-dai-tdm-quat-rx { + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <0>; + qcom,msm-cpudai-tdm-sync-src = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&quat_tdm_active &quat_tdm_dout_active>; + pinctrl-1 = <&quat_tdm_sleep &quat_tdm_dout_sleep>; + }; + qcom,msm-dai-tdm-quat-tx { + qcom,msm-cpudai-tdm-clk-internal = <1>; + qcom,msm-cpudai-tdm-sync-mode = <0>; + qcom,msm-cpudai-tdm-sync-src = <1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&quat_tdm_din_active>; + pinctrl-1 = <&quat_tdm_din_sleep>; + }; }; &pm8994_gpios { diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index ed72e18d90bc..3b067e6090e6 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -3100,7 +3100,8 @@ <&afe_pcm_tx>, <&afe_proxy_rx>, <&afe_proxy_tx>, <&incall_record_rx>, <&incall_record_tx>, <&incall_music_rx>, <&incall_music2_rx>, - <&sb_5_rx>, <&sb_6_rx>; + <&sb_5_rx>, <&sb_6_rx>, + <&usb_audio_rx>, <&usb_audio_tx>; asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", "msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.2", "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", @@ -3113,7 +3114,8 @@ "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770", "msm-dai-q6-dev.16394", - "msm-dai-q6-dev.16396"; + "msm-dai-q6-dev.16396", + "msm-dai-q6-dev.28672", "msm-dai-q6-dev.28673"; asoc-codec = <&stub_codec>; asoc-codec-names = "msm-stub-codec.1"; }; @@ -3329,6 +3331,15 @@ qcom,msm-dai-q6-dev-id = <16396>; }; + usb_audio_rx: qcom,msm-dai-q6-usb-audio-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <28672>; + }; + + usb_audio_tx: qcom,msm-dai-q6-usb-audio-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <28673>; + }; }; dai_pri_auxpcm: qcom,msm-pri-auxpcm { diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-ivi.dts b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-ivi.dts index f4ddc20e4488..54b6d0e4f132 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-ivi.dts +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-ivi.dts @@ -30,14 +30,6 @@ }; }; -&spi_9 { - status = "okay"; -}; - -&i2c_8 { - status = "okay"; -}; - &blsp1_uart2 { status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts index 18821889b150..37528ab0625e 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts @@ -127,10 +127,6 @@ status = "okay"; }; -&blsp1_uart2 { - status = "okay"; -}; - &sdhc_2 { vdd-supply = <&pm8994_l21>; qcom,vdd-voltage-level = <2950000 2950000>; diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dtsi index aa20c781175c..24ac570b0374 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dtsi @@ -73,6 +73,11 @@ compatible = "qcom,msm-imem-boot_stats"; reg = <0x6b0 32>; }; + + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; }; sdhc_2: sdhci@74a4900 { @@ -869,4 +874,15 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <2950000>; }; + + wdog: qcom,wdt@9830000 { + compatible = "qcom,msm-watchdog"; + reg = <0x9830000 0x1000>; + reg-names = "wdt-base"; + interrupts = <0 28 0>, <0 29 0>; + qcom,bark-time = <11000>; + qcom,pet-time = <10000>; + qcom,ipi-ping; + qcom,wakeup-enable; + }; }; diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 16dd7dd37f78..98657d0a6822 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -1940,7 +1940,7 @@ exit: } static int __qseecom_process_blocked_on_listener_smcinvoke( - struct qseecom_command_scm_resp *resp) + struct qseecom_command_scm_resp *resp, uint32_t app_id) { struct qseecom_registered_listener_list *list_ptr; int ret = 0; @@ -1987,9 +1987,18 @@ static int __qseecom_process_blocked_on_listener_smcinvoke( &ireq, sizeof(ireq), &continue_resp, sizeof(continue_resp)); if (ret) { - pr_err("scm_call for continue blocked req for session %d failed, ret %d\n", - session_id, ret); - goto exit; + /* retry with legacy cmd */ + qseecom.smcinvoke_support = false; + ireq.app_or_session_id = app_id; + ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, + &ireq, sizeof(ireq), + &continue_resp, sizeof(continue_resp)); + qseecom.smcinvoke_support = true; + if (ret) { + pr_err("cont block req for app %d or session %d fail\n", + app_id, session_id); + goto exit; + } } resp->result = QSEOS_RESULT_INCOMPLETE; exit: @@ -2006,7 +2015,7 @@ static int __qseecom_process_reentrancy_blocked_on_listener( resp, ptr_app, data); else return __qseecom_process_blocked_on_listener_smcinvoke( - resp); + resp, data->client.app_id); } static int __qseecom_reentrancy_process_incomplete_cmd( struct qseecom_dev_handle *data, @@ -4786,6 +4795,9 @@ int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc) resp.resp_type = desc->ret[1]; /*incomplete:unused;blocked:session_id*/ resp.data = desc->ret[2]; /*listener_id*/ + dummy_private_data.client.app_id = desc->ret[1]; + dummy_app_entry.app_id = desc->ret[1]; + mutex_lock(&app_access_lock); if (qseecom.qsee_reentrancy_support) ret = __qseecom_process_reentrancy(&resp, &dummy_app_entry, diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index b1a57d8853e8..f33673732d62 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -4689,8 +4689,8 @@ static int fg_parse_ki_coefficients(struct fg_chip *chip) #define DEFAULT_ESR_FLT_TEMP_DECIDEGC 100 #define DEFAULT_ESR_TIGHT_FLT_UPCT 3907 #define DEFAULT_ESR_BROAD_FLT_UPCT 99610 -#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT 48829 -#define DEFAULT_ESR_BROAD_LT_FLT_UPCT 148438 +#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT 30000 +#define DEFAULT_ESR_BROAD_LT_FLT_UPCT 30000 #define DEFAULT_ESR_CLAMP_MOHMS 20 #define DEFAULT_ESR_PULSE_THRESH_MA 110 #define DEFAULT_ESR_MEAS_CURR_MA 120 diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c index f2c273b0f4e0..a678e03235c0 100644 --- a/drivers/soc/qcom/glink_smem_native_xprt.c +++ b/drivers/soc/qcom/glink_smem_native_xprt.c @@ -1982,6 +1982,7 @@ static int tx_data(struct glink_transport_if *if_ptr, uint16_t cmd_id, /* Need enough space to write the command and some data */ if (size <= sizeof(cmd)) { einfo->tx_resume_needed = true; + send_tx_blocked_signal(einfo); spin_unlock_irqrestore(&einfo->write_lock, flags); srcu_read_unlock(&einfo->use_ref, rcu_id); return -EAGAIN; diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c index 3791169ec0ac..b1afd02b49bf 100644 --- a/drivers/soc/qcom/qdsp6v2/apr.c +++ b/drivers/soc/qcom/qdsp6v2/apr.c @@ -679,9 +679,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 diff --git a/drivers/soc/qcom/qdsp6v2/apr_vm.c b/drivers/soc/qcom/qdsp6v2/apr_vm.c index d0ea7b22717a..56592ac91e1b 100644 --- a/drivers/soc/qcom/qdsp6v2/apr_vm.c +++ b/drivers/soc/qcom/qdsp6v2/apr_vm.c @@ -514,7 +514,8 @@ static int apr_vm_cb_process_evt(char *buf, int len) 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]) + 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); diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 2b6e8f8240d9..147e448ed405 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -106,7 +106,7 @@ struct snd_pcm_ops { #endif #define SNDRV_PCM_IOCTL1_RESET 0 -#define SNDRV_PCM_IOCTL1_INFO 1 +/* 1 is absent slot. */ #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 #define SNDRV_PCM_IOCTL1_GSTATE 3 #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4 @@ -466,6 +466,7 @@ struct snd_pcm_substream { const struct snd_pcm_ops *ops; /* -- runtime information -- */ struct snd_pcm_runtime *runtime; + spinlock_t runtime_lock; /* -- timer section -- */ struct snd_timer *timer; /* timer */ unsigned timer_running: 1; /* time is running */ diff --git a/sound/core/pcm.c b/sound/core/pcm.c index a2c2f06060df..4fc68b126169 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -742,6 +742,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) } substream->group = &substream->self_group; spin_lock_init(&substream->self_group.lock); + spin_lock_init(&substream->runtime_lock); mutex_init(&substream->self_group.mutex); INIT_LIST_HEAD(&substream->self_group.substreams); list_add_tail(&substream->link_list, &substream->self_group.substreams); @@ -1020,9 +1021,11 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, void snd_pcm_detach_substream(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; + unsigned long flags = 0; if (PCM_RUNTIME_CHECK(substream)) return; + spin_lock_irqsave(&substream->runtime_lock, flags); runtime = substream->runtime; if (runtime->private_free != NULL) runtime->private_free(runtime); @@ -1036,6 +1039,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) put_pid(substream->pid); substream->pid = NULL; substream->pstr->substream_opened--; + spin_unlock_irqrestore(&substream->runtime_lock, flags); } static ssize_t show_pcm_class(struct device *dev, diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 2530669e2f94..23009cabcd88 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1857,8 +1857,6 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { switch (cmd) { - case SNDRV_PCM_IOCTL1_INFO: - return 0; case SNDRV_PCM_IOCTL1_RESET: return snd_pcm_lib_ioctl_reset(substream, arg); case SNDRV_PCM_IOCTL1_CHANNEL_INFO: diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 9af294c72a4d..51110252e3f3 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -197,7 +197,6 @@ static inline void snd_leave_user(mm_segment_t fs) int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) { - struct snd_pcm_runtime *runtime; struct snd_pcm *pcm = substream->pcm; struct snd_pcm_str *pstr = substream->pstr; @@ -213,12 +212,7 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) info->subdevices_count = pstr->substream_count; info->subdevices_avail = pstr->substream_count - pstr->substream_opened; strlcpy(info->subname, substream->name, sizeof(info->subname)); - runtime = substream->runtime; - /* AB: FIXME!!! This is definitely nonsense */ - if (runtime) { - info->sync = runtime->sync; - substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info); - } + return 0; } diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c index 20ecd8f18080..11ea73f019ba 100644 --- a/sound/core/pcm_timer.c +++ b/sound/core/pcm_timer.c @@ -65,9 +65,16 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) { struct snd_pcm_substream *substream; - + unsigned long ret = 0, flags = 0; + substream = timer->private_data; - return substream->runtime ? substream->runtime->timer_resolution : 0; + spin_lock_irqsave(&substream->runtime_lock, flags); + if (substream->runtime) + ret = substream->runtime->timer_resolution; + else + ret = 0; + spin_unlock_irqrestore(&substream->runtime_lock, flags); + return ret; } static int snd_pcm_timer_start(struct snd_timer * timer) diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c index 6098a49b5c7c..43f00dcff7af 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -86,6 +86,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/sound/soc/msm/msm8996.c b/sound/soc/msm/msm8996.c index 010dfa3322a0..49a70a7395ac 100644 --- a/sound/soc/msm/msm8996.c +++ b/sound/soc/msm/msm8996.c @@ -41,12 +41,16 @@ #define DRV_NAME "msm8996-asoc-snd" #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_44P1KHZ 44100 #define MSM8996_SPK_ON 1 #define MSM8996_HIFI_ON 1 @@ -73,6 +77,249 @@ 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; +/* TDM default channels */ +static int msm_pri_tdm_tx_0_ch = 2; +static int msm_pri_tdm_tx_1_ch = 2; +static int msm_pri_tdm_tx_2_ch = 2; +static int msm_pri_tdm_tx_3_ch = 2; + +static int msm_pri_tdm_rx_0_ch = 2; +static int msm_pri_tdm_rx_1_ch = 2; +static int msm_pri_tdm_rx_2_ch = 2; +static int msm_pri_tdm_rx_3_ch = 2; + +static int msm_sec_tdm_tx_0_ch = 2; +static int msm_sec_tdm_tx_1_ch = 2; +static int msm_sec_tdm_tx_2_ch = 2; +static int msm_sec_tdm_tx_3_ch = 2; + +static int msm_sec_tdm_rx_0_ch = 2; +static int msm_sec_tdm_rx_1_ch = 2; +static int msm_sec_tdm_rx_2_ch = 2; +static int msm_sec_tdm_rx_3_ch = 2; + +static int msm_tert_tdm_rx_0_ch = 2; +static int msm_tert_tdm_rx_1_ch = 2; +static int msm_tert_tdm_rx_2_ch = 2; +static int msm_tert_tdm_rx_3_ch = 2; + +static int msm_tert_tdm_tx_0_ch = 2; +static int msm_tert_tdm_tx_1_ch = 2; +static int msm_tert_tdm_tx_2_ch = 2; +static int msm_tert_tdm_tx_3_ch = 2; + +static int msm_quat_tdm_rx_0_ch = 2; +static int msm_quat_tdm_rx_1_ch = 2; +static int msm_quat_tdm_rx_2_ch = 2; +static int msm_quat_tdm_rx_3_ch = 2; + +static int msm_quat_tdm_tx_0_ch = 2; +static int msm_quat_tdm_tx_1_ch = 2; +static int msm_quat_tdm_tx_2_ch = 2; +static int msm_quat_tdm_tx_3_ch = 2; + +/* TDM default bit format */ +static int msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_pri_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_pri_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_pri_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_pri_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_pri_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_pri_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_sec_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_sec_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_sec_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_sec_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_sec_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_sec_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_tert_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_tert_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_tert_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_tert_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_tert_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_tert_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_tert_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_tert_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_quat_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_quat_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_quat_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_quat_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_quat_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_quat_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_quat_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; +static int msm_quat_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + +static int msm_pri_tdm_rate = SAMPLING_RATE_48KHZ; +static int msm_pri_tdm_slot_width = 32; +static int msm_pri_tdm_slot_num = 8; +static int msm_sec_tdm_rate = SAMPLING_RATE_48KHZ; +static int msm_sec_tdm_slot_width = 32; +static int msm_sec_tdm_slot_num = 8; +static int msm_quat_tdm_rate = SAMPLING_RATE_48KHZ; +static int msm_quat_tdm_slot_width = 32; +static int msm_quat_tdm_slot_num = 8; +static int msm_tert_tdm_rate = SAMPLING_RATE_48KHZ; +static int msm_tert_tdm_slot_width = 32; +static int msm_tert_tdm_slot_num = 8; + +static int msm_tdm_slot_width = 32; +static int msm_tdm_num_slots = 8; + +enum { + QUATERNARY_TDM_RX_0, + QUATERNARY_TDM_RX_1, + QUATERNARY_TDM_RX_2, + QUATERNARY_TDM_RX_3, + QUATERNARY_TDM_RX_4, + QUATERNARY_TDM_RX_5, + QUATERNARY_TDM_RX_6, + QUATERNARY_TDM_RX_7, + QUATERNARY_TDM_TX_0, + QUATERNARY_TDM_TX_1, + QUATERNARY_TDM_TX_2, + QUATERNARY_TDM_TX_3, + QUATERNARY_TDM_TX_4, + QUATERNARY_TDM_TX_5, + QUATERNARY_TDM_TX_6, + QUATERNARY_TDM_TX_7, + TERTIARY_TDM_RX_0, + TERTIARY_TDM_RX_1, + TERTIARY_TDM_RX_2, + TERTIARY_TDM_RX_3, + TERTIARY_TDM_RX_4, + TERTIARY_TDM_RX_5, + TERTIARY_TDM_RX_6, + TERTIARY_TDM_RX_7, + TERTIARY_TDM_TX_0, + TERTIARY_TDM_TX_1, + TERTIARY_TDM_TX_2, + TERTIARY_TDM_TX_3, + TERTIARY_TDM_TX_4, + TERTIARY_TDM_TX_5, + TERTIARY_TDM_TX_6, + TERTIARY_TDM_TX_7, + SECONDARY_TDM_RX_0, + SECONDARY_TDM_RX_1, + SECONDARY_TDM_RX_2, + SECONDARY_TDM_RX_3, + SECONDARY_TDM_RX_4, + SECONDARY_TDM_RX_5, + SECONDARY_TDM_RX_6, + SECONDARY_TDM_RX_7, + SECONDARY_TDM_TX_0, + SECONDARY_TDM_TX_1, + SECONDARY_TDM_TX_2, + SECONDARY_TDM_TX_3, + SECONDARY_TDM_TX_4, + SECONDARY_TDM_TX_5, + SECONDARY_TDM_TX_6, + SECONDARY_TDM_TX_7, + PRIMARY_TDM_RX_0, + PRIMARY_TDM_RX_1, + PRIMARY_TDM_RX_2, + PRIMARY_TDM_RX_3, + PRIMARY_TDM_RX_4, + PRIMARY_TDM_RX_5, + PRIMARY_TDM_RX_6, + PRIMARY_TDM_RX_7, + PRIMARY_TDM_TX_0, + PRIMARY_TDM_TX_1, + PRIMARY_TDM_TX_2, + PRIMARY_TDM_TX_3, + PRIMARY_TDM_TX_4, + PRIMARY_TDM_TX_5, + PRIMARY_TDM_TX_6, + PRIMARY_TDM_TX_7, + TDM_MAX, +}; + +#define TDM_SLOT_OFFSET_MAX 8 +/* TDM default offset */ +static unsigned int tdm_slot_offset[TDM_MAX][TDM_SLOT_OFFSET_MAX] = { + /* QUAT_TDM_RX */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + /* QUAT_TDM_TX */ + {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_RX */ + {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_TX */ + {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_RX */ + {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_TX */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + /* PRI_TDM_RX */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + /* PRI_TDM_TX */ + {0, 4, 0xFFFF}, + {8, 12, 0xFFFF}, + {16, 20, 0xFFFF}, + {24, 28, 0xFFFF}, + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ + {0xFFFF}, /* not used */ +}; + static struct platform_device *spdev; static int ext_us_amp_gpio = -1; static int msm8996_spk_control = 1; @@ -104,6 +351,7 @@ 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 *usb_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", @@ -118,12 +366,55 @@ static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four", static char const *hdmi_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96", "KHZ_192"}; +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"}; +static const char *const tdm_rate_text[] = {"8000", "16000", "48000"}; + +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_88P2", + "KHZ_96", "KHZ_176P4", "KHZ_192"}; + +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, usb_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, usb_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 const char *const auxpcm_rate_text[] = {"8000", "16000"}; static const struct soc_enum msm8996_auxpcm_enum[] = { SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text), }; +struct usb_be_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +static struct usb_be_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct usb_be_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + static struct afe_clk_set mi2s_tx_clk = { AFE_API_VERSION_I2S_CONFIG, Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, @@ -1256,6 +1547,328 @@ static int hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol, 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 = 0; + + switch (usb_rx_cfg.sample_rate) { + 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 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_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 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 = 0; + + switch (usb_tx_cfg.sample_rate) { + 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 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_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 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 msm8996_auxpcm_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1296,6 +1909,2179 @@ static int msm_proxy_rx_ch_put(struct snd_kcontrol *kcontrol, return 1; } +static int msm_pri_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_pri_tdm_tx_0_ch = %d\n", __func__, + msm_pri_tdm_tx_0_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_tx_0_ch - 1; + return 0; +} + +static int msm_pri_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_tx_0_ch = %d\n", __func__, + msm_pri_tdm_tx_0_ch); + return 0; +} + +static int msm_pri_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: pri_tdm_tx_1_ch = %d\n", __func__, + msm_pri_tdm_tx_1_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_tx_1_ch - 1; + return 0; +} + +static int msm_pri_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_tx_1_ch = %d\n", __func__, + msm_pri_tdm_tx_1_ch); + return 0; +} + +static int msm_pri_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_pri_tdm_tx_2_ch = %d\n", __func__, + msm_pri_tdm_tx_2_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_tx_2_ch - 1; + return 0; +} + +static int msm_pri_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_tx_2_ch = %d\n", __func__, + msm_pri_tdm_tx_2_ch); + return 0; +} +static int msm_pri_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_pri_tdm_tx_3_ch = %d\n", __func__, + msm_pri_tdm_tx_3_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_tx_3_ch - 1; + return 0; +} + +static int msm_pri_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_tx_3_ch = %d\n", __func__, + msm_pri_tdm_tx_3_ch); + return 0; +} + +static int msm_pri_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_pri_tdm_rx_0_ch = %d\n", __func__, + msm_pri_tdm_rx_0_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_rx_0_ch - 1; + return 0; +} + +static int msm_pri_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_rx_0_ch = %d\n", __func__, + msm_pri_tdm_rx_0_ch); + return 0; +} + +static int msm_pri_tdm_rx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_pri_tdm_rx_1_ch = %d\n", __func__, + msm_pri_tdm_rx_1_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_rx_1_ch - 1; + return 0; +} + +static int msm_pri_tdm_rx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_rx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_rx_1_ch = %d\n", __func__, + msm_pri_tdm_rx_1_ch); + return 0; +} + +static int msm_pri_tdm_rx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_pri_tdm_rx_2_ch = %d\n", __func__, + msm_pri_tdm_rx_2_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_rx_2_ch - 1; + return 0; +} + +static int msm_pri_tdm_rx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_rx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_rx_2_ch = %d\n", __func__, + msm_pri_tdm_rx_2_ch); + return 0; +} + +static int msm_pri_tdm_rx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_pri_tdm_rx_3_ch = %d\n", __func__, + msm_pri_tdm_rx_3_ch); + ucontrol->value.integer.value[0] = msm_pri_tdm_rx_3_ch - 1; + return 0; +} + +static int msm_pri_tdm_rx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_pri_tdm_rx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_pri_tdm_rx_3_ch = %d\n", __func__, + msm_pri_tdm_rx_3_ch); + return 0; +} + +static int msm_pri_tdm_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_pri_tdm_rate; + pr_debug("%s: msm_pri_tdm_rate = %d\n", __func__, msm_pri_tdm_rate); + return 0; +} +static int msm_pri_tdm_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_pri_tdm_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + msm_pri_tdm_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + default: + msm_pri_tdm_rate = SAMPLING_RATE_48KHZ; + break; + } + pr_debug("%s: msm_pri_tdm_rate = %d\n", + __func__, msm_pri_tdm_rate); + return 0; +} + +static int msm_sec_tdm_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_sec_tdm_rate; + pr_debug("%s: msm_sec_tdm_rate = %d\n", __func__, msm_sec_tdm_rate); + return 0; +} + +static int msm_sec_tdm_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_sec_tdm_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + msm_sec_tdm_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + default: + msm_sec_tdm_rate = SAMPLING_RATE_48KHZ; + break; + } + pr_debug("%s: msm_sec_tdm_rate = %d\n", + __func__, msm_sec_tdm_rate); + return 0; +} + +static int msm_tert_tdm_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_tert_tdm_rate; + pr_debug("%s: msm_tert_tdm_rate = %d\n", __func__, msm_tert_tdm_rate); + return 0; +} + +static int msm_tert_tdm_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_tert_tdm_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + msm_tert_tdm_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + default: + msm_tert_tdm_rate = SAMPLING_RATE_48KHZ; + break; + } + pr_debug("%s: msm_tert_tdm_rate = %d\n", + __func__, msm_tert_tdm_rate); + return 0; +} + +static int msm_quat_tdm_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_quat_tdm_rate; + pr_debug("%s: msm_quat_tdm_rate = %d\n", __func__, msm_quat_tdm_rate); + return 0; +} +static int msm_quat_tdm_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_quat_tdm_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + msm_quat_tdm_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + default: + msm_quat_tdm_rate = SAMPLING_RATE_48KHZ; + break; + } + pr_debug("%s: msm_quat_tdm_rate = %d\n", + __func__, msm_quat_tdm_rate); + return 0; +} + +static int msm_pri_tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_pri_tdm_slot_width; + pr_debug("%s: msm_pri_tdm_slot_width = %d\n", + __func__, msm_pri_tdm_slot_width); + return 0; +} + +static int msm_pri_tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_pri_tdm_slot_width = 16; + break; + case 1: + msm_pri_tdm_slot_width = 24; + break; + case 2: + default: + msm_pri_tdm_slot_width = 32; + break; + } + pr_debug("%s: msm_pri_tdm_slot_width= %d\n", + __func__, msm_pri_tdm_slot_width); + return 0; +} + +static int msm_sec_tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_sec_tdm_slot_width; + pr_debug("%s: msm_sec_tdm_slot_width = %d\n", + __func__, msm_sec_tdm_slot_width); + return 0; +} + +static int msm_sec_tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_sec_tdm_slot_width = 16; + break; + case 1: + msm_sec_tdm_slot_width = 24; + break; + case 2: + default: + msm_sec_tdm_slot_width = 32; + break; + } + pr_debug("%s: msm_sec_tdm_slot_width= %d\n", + __func__, msm_sec_tdm_slot_width); + return 0; +} + +static int msm_tert_tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_tert_tdm_slot_width; + pr_debug("%s: msm_tert_tdm_slot_width = %d\n", + __func__, msm_tert_tdm_slot_width); + return 0; +} + +static int msm_tert_tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_tert_tdm_slot_width = 16; + break; + case 1: + msm_tert_tdm_slot_width = 24; + break; + case 2: + default: + msm_tert_tdm_slot_width = 32; + break; + } + pr_debug("%s: msm_tert_tdm_slot_width= %d\n", + __func__, msm_tert_tdm_slot_width); + return 0; +} + +static int msm_quat_tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_quat_tdm_slot_width; + pr_debug("%s: msm_quat_tdm_slot_width = %d\n", + __func__, msm_quat_tdm_slot_width); + return 0; +} + +static int msm_quat_tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_quat_tdm_slot_width = 16; + break; + case 1: + msm_quat_tdm_slot_width = 24; + break; + case 2: + default: + msm_quat_tdm_slot_width = 32; + break; + } + pr_debug("%s: msm_quat_tdm_slot_width= %d\n", + __func__, msm_quat_tdm_slot_width); + return 0; +} + + +static int msm_pri_tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_slot_num) { + case 1: + ucontrol->value.integer.value[0] = 0; + break; + case 2: + ucontrol->value.integer.value[0] = 1; + break; + case 4: + ucontrol->value.integer.value[0] = 2; + break; + case 8: + ucontrol->value.integer.value[0] = 3; + break; + case 16: + ucontrol->value.integer.value[0] = 4; + break; + case 32: + default: + ucontrol->value.integer.value[0] = 5; + break; + } + + pr_debug("%s: msm_pri_tdm_slot_num = %d\n", + __func__, msm_pri_tdm_slot_num); + return 0; +} + +static int msm_pri_tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_pri_tdm_slot_num = 1; + break; + case 1: + msm_pri_tdm_slot_num = 2; + break; + case 2: + msm_pri_tdm_slot_num = 4; + break; + case 3: + msm_pri_tdm_slot_num = 8; + break; + case 4: + msm_pri_tdm_slot_num = 16; + break; + case 5: + msm_pri_tdm_slot_num = 32; + break; + default: + msm_pri_tdm_slot_num = 8; + break; + } + pr_debug("%s: msm_pri_tdm_slot_num = %d\n", + __func__, msm_pri_tdm_slot_num); + return 0; +} + +static int msm_sec_tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_slot_num) { + case 1: + ucontrol->value.integer.value[0] = 0; + break; + case 2: + ucontrol->value.integer.value[0] = 1; + break; + case 4: + ucontrol->value.integer.value[0] = 2; + break; + case 8: + ucontrol->value.integer.value[0] = 3; + break; + case 16: + ucontrol->value.integer.value[0] = 4; + break; + case 32: + default: + ucontrol->value.integer.value[0] = 5; + break; + } + + pr_debug("%s: msm_sec_tdm_slot_num = %d\n", + __func__, msm_sec_tdm_slot_num); + return 0; +} + +static int msm_sec_tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_sec_tdm_slot_num = 1; + break; + case 1: + msm_sec_tdm_slot_num = 2; + break; + case 2: + msm_sec_tdm_slot_num = 4; + break; + case 3: + msm_sec_tdm_slot_num = 8; + break; + case 4: + msm_sec_tdm_slot_num = 16; + break; + case 5: + msm_sec_tdm_slot_num = 32; + break; + default: + msm_sec_tdm_slot_num = 8; + break; + } + pr_debug("%s: msm_sec_tdm_slot_num = %d\n", + __func__, msm_sec_tdm_slot_num); + return 0; +} + +static int msm_tert_tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_slot_num) { + case 1: + ucontrol->value.integer.value[0] = 0; + break; + case 2: + ucontrol->value.integer.value[0] = 1; + break; + case 4: + ucontrol->value.integer.value[0] = 2; + break; + case 8: + ucontrol->value.integer.value[0] = 3; + break; + case 16: + ucontrol->value.integer.value[0] = 4; + break; + case 32: + default: + ucontrol->value.integer.value[0] = 5; + break; + } + + pr_debug("%s: msm_tert_tdm_slot_num = %d\n", + __func__, msm_tert_tdm_slot_num); + return 0; +} + +static int msm_tert_tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_tert_tdm_slot_num = 1; + break; + case 1: + msm_tert_tdm_slot_num = 2; + break; + case 2: + msm_tert_tdm_slot_num = 4; + break; + case 3: + msm_tert_tdm_slot_num = 8; + break; + case 4: + msm_tert_tdm_slot_num = 16; + break; + case 5: + msm_tert_tdm_slot_num = 32; + break; + default: + msm_tert_tdm_slot_num = 8; + break; + } + pr_debug("%s: msm_tert_tdm_slot_num = %d\n", + __func__, msm_tert_tdm_slot_num); + return 0; +} + +static int msm_quat_tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_slot_num) { + case 1: + ucontrol->value.integer.value[0] = 0; + break; + case 2: + ucontrol->value.integer.value[0] = 1; + break; + case 4: + ucontrol->value.integer.value[0] = 2; + break; + case 8: + ucontrol->value.integer.value[0] = 3; + break; + case 16: + ucontrol->value.integer.value[0] = 4; + break; + case 32: + default: + ucontrol->value.integer.value[0] = 5; + break; + } + + pr_debug("%s: msm_quat_tdm_slot_num = %d\n", + __func__, msm_quat_tdm_slot_num); + return 0; +} +static int msm_quat_tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_quat_tdm_slot_num = 1; + break; + case 1: + msm_quat_tdm_slot_num = 2; + break; + case 2: + msm_quat_tdm_slot_num = 4; + break; + case 3: + msm_quat_tdm_slot_num = 8; + break; + case 4: + msm_quat_tdm_slot_num = 16; + break; + case 5: + msm_quat_tdm_slot_num = 32; + break; + default: + msm_quat_tdm_slot_num = 8; + break; + } + pr_debug("%s: msm_quat_tdm_slot_num = %d\n", + __func__, msm_quat_tdm_slot_num); + return 0; +} + +static int msm_tdm_slot_mapping_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_multi_mixer_control *mc = + (struct soc_multi_mixer_control *)kcontrol->private_value; + unsigned int *slot_offset; + int i; + + if (mc->shift >= TDM_MAX) { + pr_err("%s invalid port index %d\n", __func__, mc->shift); + return -EINVAL; + } + + slot_offset = tdm_slot_offset[mc->shift]; + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + ucontrol->value.integer.value[i] = slot_offset[i]; + pr_debug("%s port index %d offset %d value %d\n", + __func__, mc->shift, i, slot_offset[i]); + } + + return 0; +} + +static int msm_tdm_slot_mapping_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_multi_mixer_control *mc = + (struct soc_multi_mixer_control *)kcontrol->private_value; + unsigned int *slot_offset; + int i; + + if (mc->shift >= TDM_MAX) { + pr_err("%s invalid port index %d\n", __func__, mc->shift); + return -EINVAL; + } + + slot_offset = tdm_slot_offset[mc->shift]; + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + slot_offset[i] = ucontrol->value.integer.value[i]; + pr_debug("%s port index %d offset %d value %d\n", + __func__, mc->shift, i, slot_offset[i]); + } + + return 0; +} + +static int msm_sec_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_rx_0_ch = %d\n", __func__, + msm_sec_tdm_rx_0_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_rx_0_ch - 1; + return 0; +} + +static int msm_sec_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_rx_0_ch = %d\n", __func__, + msm_sec_tdm_rx_0_ch); + return 0; +} + +static int msm_sec_tdm_rx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_rx_1_ch = %d\n", __func__, + msm_sec_tdm_rx_1_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_rx_1_ch - 1; + return 0; +} + +static int msm_sec_tdm_rx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_rx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_rx_1_ch = %d\n", __func__, + msm_sec_tdm_rx_1_ch); + return 0; +} + +static int msm_sec_tdm_rx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_rx_2_ch = %d\n", __func__, + msm_sec_tdm_rx_2_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_rx_2_ch - 1; + return 0; +} + +static int msm_sec_tdm_rx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_rx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_rx_2_ch = %d\n", __func__, + msm_sec_tdm_rx_2_ch); + return 0; +} + +static int msm_sec_tdm_rx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_rx_3_ch = %d\n", __func__, + msm_sec_tdm_rx_3_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_rx_3_ch - 1; + return 0; +} + +static int msm_sec_tdm_rx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_rx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_rx_3_ch = %d\n", __func__, + msm_sec_tdm_rx_3_ch); + return 0; +} + +static int msm_sec_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_tx_0_ch = %d\n", __func__, + msm_sec_tdm_tx_0_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_tx_0_ch - 1; + return 0; +} + +static int msm_sec_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_tx_0_ch = %d\n", __func__, + msm_sec_tdm_tx_0_ch); + return 0; +} + +static int msm_sec_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_tx_1_ch = %d\n", __func__, + msm_sec_tdm_tx_1_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_tx_1_ch - 1; + return 0; +} + +static int msm_sec_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_tx_1_ch = %d\n", __func__, + msm_sec_tdm_tx_1_ch); + return 0; +} +static int msm_sec_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_tx_2_ch = %d\n", __func__, + msm_sec_tdm_tx_2_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_tx_2_ch - 1; + return 0; +} + +static int msm_sec_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_tx_2_ch = %d\n", __func__, + msm_sec_tdm_tx_2_ch); + return 0; +} + +static int msm_sec_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_sec_tdm_tx_3_ch = %d\n", __func__, + msm_sec_tdm_tx_3_ch); + ucontrol->value.integer.value[0] = msm_sec_tdm_tx_3_ch - 1; + return 0; +} + +static int msm_sec_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_sec_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_sec_tdm_tx_3_ch = %d\n", __func__, + msm_sec_tdm_tx_3_ch); + return 0; +} + +static int msm_tert_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_rx_0_ch = %d\n", __func__, + msm_tert_tdm_rx_0_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_rx_0_ch - 1; + return 0; +} + +static int msm_tert_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_rx_0_ch = %d\n", __func__, + msm_tert_tdm_rx_0_ch); + return 0; +} +static int msm_tert_tdm_rx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_rx_1_ch = %d\n", __func__, + msm_tert_tdm_rx_1_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_rx_1_ch - 1; + return 0; +} + +static int msm_tert_tdm_rx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_rx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_rx_1_ch = %d\n", __func__, + msm_tert_tdm_rx_1_ch); + return 0; +} + +static int msm_tert_tdm_rx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_rx_2_ch = %d\n", __func__, + msm_tert_tdm_rx_2_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_rx_2_ch - 1; + return 0; +} + +static int msm_tert_tdm_rx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_rx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_rx_2_ch = %d\n", __func__, + msm_tert_tdm_rx_2_ch); + return 0; +} + +static int msm_tert_tdm_rx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_rx_3_ch = %d\n", __func__, + msm_tert_tdm_rx_3_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_rx_3_ch - 1; + return 0; +} + +static int msm_tert_tdm_rx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_rx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_rx_3_ch = %d\n", __func__, + msm_tert_tdm_rx_3_ch); + return 0; +} + +static int msm_tert_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_tx_0_ch = %d\n", __func__, + msm_tert_tdm_tx_0_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_tx_0_ch - 1; + return 0; +} + +static int msm_tert_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_tx_0_ch = %d\n", __func__, + msm_tert_tdm_tx_0_ch); + return 0; +} + +static int msm_tert_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_tx_1_ch = %d\n", __func__, + msm_tert_tdm_tx_1_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_tx_1_ch - 1; + return 0; +} + +static int msm_tert_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_tx_1_ch = %d\n", __func__, + msm_tert_tdm_tx_1_ch); + return 0; +} + +static int msm_tert_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_tx_2_ch = %d\n", __func__, + msm_tert_tdm_tx_2_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_tx_2_ch - 1; + return 0; +} + +static int msm_tert_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_tx_2_ch = %d\n", __func__, + msm_tert_tdm_tx_2_ch); + return 0; +} + +static int msm_tert_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_tert_tdm_tx_3_ch = %d\n", __func__, + msm_tert_tdm_tx_3_ch); + ucontrol->value.integer.value[0] = msm_tert_tdm_tx_3_ch - 1; + return 0; +} + +static int msm_tert_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_tert_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_tert_tdm_tx_3_ch = %d\n", __func__, + msm_tert_tdm_tx_3_ch); + return 0; +} + +static int msm_quat_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_rx_0_ch = %d\n", __func__, + msm_quat_tdm_rx_0_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_rx_0_ch - 1; + return 0; +} + +static int msm_quat_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_rx_0_ch = %d\n", __func__, + msm_quat_tdm_rx_0_ch); + return 0; +} + +static int msm_quat_tdm_rx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_rx_1_ch = %d\n", __func__, + msm_quat_tdm_rx_1_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_rx_1_ch - 1; + return 0; +} + +static int msm_quat_tdm_rx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_rx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_rx_1_ch = %d\n", __func__, + msm_quat_tdm_rx_1_ch); + return 0; +} + +static int msm_quat_tdm_rx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_rx_2_ch = %d\n", __func__, + msm_quat_tdm_rx_2_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_rx_2_ch - 1; + return 0; +} + +static int msm_quat_tdm_rx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_rx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_rx_2_ch = %d\n", __func__, + msm_quat_tdm_rx_2_ch); + return 0; +} + +static int msm_quat_tdm_rx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_rx_3_ch = %d\n", __func__, + msm_quat_tdm_rx_3_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_rx_3_ch - 1; + return 0; +} + +static int msm_quat_tdm_rx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_rx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_rx_3_ch = %d\n", __func__, + msm_quat_tdm_rx_3_ch); + return 0; +} +static int msm_quat_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_tx_0_ch = %d\n", __func__, + msm_quat_tdm_tx_0_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_tx_0_ch - 1; + return 0; +} + +static int msm_quat_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_tx_0_ch = %d\n", __func__, + msm_quat_tdm_tx_0_ch); + return 0; +} + +static int msm_quat_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_tx_1_ch = %d\n", __func__, + msm_quat_tdm_tx_1_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_tx_1_ch - 1; + return 0; +} + +static int msm_quat_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_tx_1_ch = %d\n", __func__, + msm_quat_tdm_tx_1_ch); + return 0; +} + +static int msm_quat_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_tx_2_ch = %d\n", __func__, + msm_quat_tdm_tx_2_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_tx_2_ch - 1; + return 0; +} + +static int msm_quat_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_tx_2_ch = %d\n", __func__, + msm_quat_tdm_tx_2_ch); + return 0; +} + +static int msm_quat_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: msm_quat_tdm_tx_3_ch = %d\n", __func__, + msm_quat_tdm_tx_3_ch); + ucontrol->value.integer.value[0] = msm_quat_tdm_tx_3_ch - 1; + return 0; +} + +static int msm_quat_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + msm_quat_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1; + pr_debug("%s: msm_quat_tdm_tx_3_ch = %d\n", __func__, + msm_quat_tdm_tx_3_ch); + return 0; +} + +static int msm_pri_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_tx_0_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: msm_pri_tdm_tx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_tx_0_bit_format = %d\n", + __func__, msm_pri_tdm_tx_0_bit_format); + return 0; +} + +static int msm_pri_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_tx_1_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: msm_pri_tdm_tx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_tx_1_bit_format = %d\n", + __func__, msm_pri_tdm_tx_1_bit_format); + return 0; +} + +static int msm_pri_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_tx_2_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: msm_pri_tdm_tx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_tx_2_bit_format = %d\n", + __func__, msm_pri_tdm_tx_2_bit_format); + return 0; +} + +static int msm_pri_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_tx_3_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: msm_pri_tdm_tx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_tx_3_bit_format = %d\n", + __func__, msm_pri_tdm_tx_3_bit_format); + return 0; +} + +static int msm_pri_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_rx_0_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: msm_pri_tdm_rx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_rx_0_bit_format = %d\n", + __func__, msm_pri_tdm_rx_0_bit_format); + return 0; +} + +static int msm_pri_tdm_rx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_rx_1_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: msm_pri_tdm_rx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_rx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_rx_1_bit_format = %d\n", + __func__, msm_pri_tdm_rx_1_bit_format); + return 0; +} + +static int msm_pri_tdm_rx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_rx_2_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: msm_pri_tdm_rx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_rx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_rx_2_bit_format = %d\n", + __func__, msm_pri_tdm_rx_2_bit_format); + return 0; +} + +static int msm_pri_tdm_rx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_pri_tdm_rx_3_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: msm_pri_tdm_rx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_pri_tdm_rx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_pri_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_pri_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_pri_tdm_rx_3_bit_format = %d\n", + __func__, msm_pri_tdm_rx_3_bit_format); + return 0; +} + +static int msm_sec_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_rx_0_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: msm_sec_tdm_rx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_sec_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_rx_0_bit_format = %d\n", + __func__, msm_sec_tdm_rx_0_bit_format); + return 0; +} + +static int msm_sec_tdm_rx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_rx_1_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: msm_sec_tdm_rx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_sec_tdm_rx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_rx_1_bit_format = %d\n", + __func__, msm_sec_tdm_rx_1_bit_format); + return 0; +} + +static int msm_sec_tdm_rx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_rx_2_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: msm_sec_tdm_rx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_sec_tdm_rx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_rx_2_bit_format = %d\n", + __func__, msm_sec_tdm_rx_2_bit_format); + return 0; +} + +static int msm_sec_tdm_rx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_rx_3_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: msm_sec_tdm_rx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_sec_tdm_rx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_rx_3_bit_format = %d\n", + __func__, msm_sec_tdm_rx_3_bit_format); + return 0; +} + +static int msm_sec_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_tx_0_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: msm_sec_tdm_tx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_sec_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_tx_0_bit_format = %d\n", + __func__, msm_sec_tdm_tx_0_bit_format); + return 0; +} + +static int msm_sec_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_tx_1_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: msm_sec_tdm_tx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_sec_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_tx_1_bit_format = %d\n", + __func__, msm_sec_tdm_tx_1_bit_format); + return 0; +} + +static int msm_sec_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_tx_2_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: msm_sec_tdm_tx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} +static int msm_sec_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_tx_2_bit_format = %d\n", + __func__, msm_sec_tdm_tx_2_bit_format); + return 0; +} + +static int msm_sec_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_tx_3_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: msm_sec_tdm_tx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_sec_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_sec_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_sec_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_sec_tdm_tx_3_bit_format = %d\n", + __func__, msm_sec_tdm_tx_3_bit_format); + return 0; +} + +static int msm_tert_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_rx_0_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: msm_tert_tdm_rx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_rx_0_bit_format = %d\n", + __func__, msm_tert_tdm_rx_0_bit_format); + return 0; +} + +static int msm_tert_tdm_rx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_rx_1_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: msm_tert_tdm_rx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_rx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_rx_1_bit_format = %d\n", + __func__, msm_tert_tdm_rx_1_bit_format); + return 0; +} + +static int msm_tert_tdm_rx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_rx_2_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: msm_tert_tdm_rx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_rx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_rx_2_bit_format = %d\n", + __func__, msm_tert_tdm_rx_2_bit_format); + return 0; +} + +static int msm_tert_tdm_rx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_rx_3_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: msm_tert_tdm_rx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_rx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_rx_3_bit_format = %d\n", + __func__, msm_tert_tdm_rx_3_bit_format); + return 0; +} + +static int msm_tert_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_tx_0_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: msm_tert_tdm_tx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_tx_0_bit_format = %d\n", + __func__, msm_tert_tdm_tx_0_bit_format); + return 0; +} + +static int msm_tert_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_tx_1_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: msm_tert_tdm_tx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_tx_1_bit_format = %d\n", + __func__, msm_tert_tdm_tx_1_bit_format); + return 0; +} + +static int msm_tert_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_tx_2_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: msm_tert_tdm_tx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_tx_2_bit_format = %d\n", + __func__, msm_tert_tdm_tx_2_bit_format); + return 0; +} + +static int msm_tert_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_tert_tdm_tx_3_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: msm_tert_tdm_tx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_tert_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_tert_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_tert_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_tert_tdm_tx_3_bit_format = %d\n", + __func__, msm_tert_tdm_tx_3_bit_format); + return 0; +} + +static int msm_quat_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_rx_0_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: msm_quat_tdm_rx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_quat_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_rx_0_bit_format = %d\n", + __func__, msm_quat_tdm_rx_0_bit_format); + return 0; +} + +static int msm_quat_tdm_rx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_rx_1_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: msm_quat_tdm_rx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} +static int msm_quat_tdm_rx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_rx_1_bit_format = %d\n", + __func__, msm_quat_tdm_rx_1_bit_format); + return 0; +} + +static int msm_quat_tdm_rx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_rx_2_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: msm_quat_tdm_rx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_quat_tdm_rx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_rx_2_bit_format = %d\n", + __func__, msm_quat_tdm_rx_2_bit_format); + return 0; +} + +static int msm_quat_tdm_rx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_rx_3_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: msm_quat_tdm_rx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_quat_tdm_rx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_rx_3_bit_format = %d\n", + __func__, msm_quat_tdm_rx_3_bit_format); + return 0; +} + +static int msm_quat_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_tx_0_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: msm_quat_tdm_tx_0_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} +static int msm_quat_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_tx_0_bit_format = %d\n", + __func__, msm_quat_tdm_tx_0_bit_format); + return 0; +} + +static int msm_quat_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_tx_1_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: msm_quat_tdm_tx_1_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_quat_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_tx_1_bit_format = %d\n", + __func__, msm_quat_tdm_tx_1_bit_format); + return 0; +} +static int msm_quat_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_tx_2_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: msm_quat_tdm_tx_2_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} + +static int msm_quat_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_tx_2_bit_format = %d\n", + __func__, msm_quat_tdm_tx_2_bit_format); + return 0; +} + +static int msm_quat_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_quat_tdm_tx_3_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: msm_quat_tdm_tx_3_bit_format = %ld\n", + __func__, ucontrol->value.integer.value[0]); + return 0; +} +static int msm_quat_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + msm_quat_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + msm_quat_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: msm_quat_tdm_tx_3_bit_format = %d\n", + __func__, msm_quat_tdm_tx_3_bit_format); + return 0; +} + + static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -1558,14 +4344,713 @@ static int msm_slim_5_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 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); + + 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; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return 0; +} +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); - pr_debug("%s:\n", __func__); rate->min = rate->max = SAMPLING_RATE_48KHZ; + + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_TX: + channels->min = channels->max = msm_pri_tdm_tx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_tx_0_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + channels->min = channels->max = msm_pri_tdm_tx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_tx_1_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + channels->min = channels->max = msm_pri_tdm_tx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_tx_2_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + channels->min = channels->max = msm_pri_tdm_tx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_tx_3_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX: + channels->min = channels->max = msm_pri_tdm_rx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_rx_0_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + channels->min = channels->max = msm_pri_tdm_rx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_rx_1_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + channels->min = channels->max = msm_pri_tdm_rx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_rx_2_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + channels->min = channels->max = msm_pri_tdm_rx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_pri_tdm_rx_3_bit_format); + rate->min = rate->max = msm_pri_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + channels->min = channels->max = msm_sec_tdm_rx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_rx_0_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + channels->min = channels->max = msm_sec_tdm_rx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_rx_1_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + channels->min = channels->max = msm_sec_tdm_rx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_rx_2_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + channels->min = channels->max = msm_sec_tdm_rx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_rx_3_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + channels->min = channels->max = msm_sec_tdm_tx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_tx_0_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + channels->min = channels->max = msm_sec_tdm_tx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_tx_1_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + channels->min = channels->max = msm_sec_tdm_tx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_tx_2_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + channels->min = channels->max = msm_sec_tdm_tx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_tdm_tx_3_bit_format); + rate->min = rate->max = msm_sec_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + channels->min = channels->max = msm_tert_tdm_rx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_rx_0_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + channels->min = channels->max = msm_tert_tdm_rx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_rx_1_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + channels->min = channels->max = msm_tert_tdm_rx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_rx_2_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + channels->min = channels->max = msm_tert_tdm_rx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_rx_3_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + channels->min = channels->max = msm_tert_tdm_tx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_tx_0_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + channels->min = channels->max = msm_tert_tdm_tx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_tx_1_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + channels->min = channels->max = msm_tert_tdm_tx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_tx_2_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + channels->min = channels->max = msm_tert_tdm_tx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_tdm_tx_3_bit_format); + rate->min = rate->max = msm_tert_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + channels->min = channels->max = msm_quat_tdm_rx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_rx_0_bit_format); + rate->min = rate->max = msm_quat_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + channels->min = channels->max = msm_quat_tdm_rx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_rx_1_bit_format); + rate->min = rate->max = msm_quat_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + channels->min = channels->max = msm_quat_tdm_rx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_rx_2_bit_format); + rate->min = rate->max = msm_quat_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + channels->min = channels->max = msm_quat_tdm_rx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_rx_3_bit_format); + rate->min = rate->max = msm_quat_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + channels->min = channels->max = msm_quat_tdm_tx_0_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_tx_0_bit_format); + rate->min = rate->max = msm_quat_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + channels->min = channels->max = msm_quat_tdm_tx_1_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_tx_1_bit_format); + rate->min = rate->max = msm_quat_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + channels->min = channels->max = msm_quat_tdm_tx_2_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_tx_2_bit_format); + rate->min = rate->max = msm_quat_tdm_rate; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + channels->min = channels->max = msm_quat_tdm_tx_3_ch; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_tdm_tx_3_bit_format); + rate->min = rate->max = msm_quat_tdm_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; + unsigned int i = 0; + + if ((slots != 16) && (slots != 8)) { + 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 msm8996_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; + 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); + + rate = params_rate(params); + channels = params_channels(params); + if (channels < 1 || channels > 8) { + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + + 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 channel HW configuration should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + slot_width = msm_tdm_slot_width; + break; + default: + pr_err("%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + + slots = msm_tdm_num_slots; + + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_1: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_2: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_3: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_3]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_4: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_4]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_5: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_5]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_6: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_6]; + break; + case AFE_PORT_ID_PRIMARY_TDM_RX_7: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_7]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_0]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_1: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_1]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_2: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_2]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_3: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_3]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_4: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_4]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_5: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_5]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_6: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_6]; + break; + case AFE_PORT_ID_PRIMARY_TDM_TX_7: + slots = msm_pri_tdm_slot_num; + slot_width = msm_pri_tdm_slot_width; + slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_7]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_1: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_2: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_3: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_4: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_4]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_5: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_5]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_6: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_6]; + break; + case AFE_PORT_ID_SECONDARY_TDM_RX_7: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_7]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_0]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_1: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_1]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_2: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_2]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_3: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_3]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_4: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_4]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_5: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_5]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_6: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_6]; + break; + case AFE_PORT_ID_SECONDARY_TDM_TX_7: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; + slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_7]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_1: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_2: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_3: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_4: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_4]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_5: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_5]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_6: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_6]; + break; + case AFE_PORT_ID_TERTIARY_TDM_RX_7: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_RX_7]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_0]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_1: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_1]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_2: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_2]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_3: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_3]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_4: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_4]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_5: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_5]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_6: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_6]; + break; + case AFE_PORT_ID_TERTIARY_TDM_TX_7: + slots = msm_tert_tdm_slot_num; + slot_width = msm_tert_tdm_slot_width; + slot_offset = tdm_slot_offset[TERTIARY_TDM_TX_7]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_1: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_2: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_3: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_4: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_4]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_5: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_5]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_6: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_6]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_RX_7]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_0]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_1: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_1]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_2: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_2]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_3: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_3]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_4: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_4]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_5: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_5]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_6: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_6]; + break; + case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + slots = msm_quat_tdm_slot_num; + slot_width = msm_quat_tdm_slot_width; + slot_offset = tdm_slot_offset[QUATERNARY_TDM_TX_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) { + 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; + } + } + + 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 struct snd_soc_ops msm8996_tdm_be_ops = { + .hw_params = msm8996_tdm_snd_hw_params, +}; + + static const struct soc_enum msm_snd_enum[] = { SOC_ENUM_SINGLE_EXT(2, spk_function), SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text), @@ -1587,6 +5072,14 @@ static const struct soc_enum msm_snd_enum[] = { 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), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_ch_text), tdm_ch_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_bit_format_text), + tdm_bit_format_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_rate_text), tdm_rate_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_slot_num_text), + tdm_slot_num_text), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_slot_width_text), + tdm_slot_width_text), }; static const struct snd_kcontrol_new msm_snd_controls[] = { @@ -1633,6 +5126,462 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { 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), + 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("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("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_TX_0 Channels", msm_snd_enum[16], + msm_pri_tdm_tx_0_ch_get, msm_pri_tdm_tx_0_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Channels", msm_snd_enum[16], + msm_pri_tdm_tx_1_ch_get, msm_pri_tdm_tx_1_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Channels", msm_snd_enum[16], + msm_pri_tdm_tx_2_ch_get, msm_pri_tdm_tx_2_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Channels", msm_snd_enum[16], + msm_pri_tdm_tx_3_ch_get, msm_pri_tdm_tx_3_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", msm_snd_enum[16], + msm_pri_tdm_rx_0_ch_get, msm_pri_tdm_rx_0_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Channels", msm_snd_enum[16], + msm_pri_tdm_rx_1_ch_get, msm_pri_tdm_rx_1_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Channels", msm_snd_enum[16], + msm_pri_tdm_rx_2_ch_get, msm_pri_tdm_rx_2_ch_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Channels", msm_snd_enum[16], + msm_pri_tdm_rx_3_ch_get, msm_pri_tdm_rx_3_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", msm_snd_enum[16], + msm_sec_tdm_rx_0_ch_get, msm_sec_tdm_rx_0_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Channels", msm_snd_enum[16], + msm_sec_tdm_rx_1_ch_get, msm_sec_tdm_rx_1_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Channels", msm_snd_enum[16], + msm_sec_tdm_rx_2_ch_get, msm_sec_tdm_rx_2_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Channels", msm_snd_enum[16], + msm_sec_tdm_rx_3_ch_get, msm_sec_tdm_rx_3_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", msm_snd_enum[16], + msm_sec_tdm_tx_0_ch_get, msm_sec_tdm_tx_0_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Channels", msm_snd_enum[16], + msm_sec_tdm_tx_1_ch_get, msm_sec_tdm_tx_1_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Channels", msm_snd_enum[16], + msm_sec_tdm_tx_2_ch_get, msm_sec_tdm_tx_2_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Channels", msm_snd_enum[16], + msm_sec_tdm_tx_3_ch_get, msm_sec_tdm_tx_3_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", msm_snd_enum[16], + msm_tert_tdm_rx_0_ch_get, msm_tert_tdm_rx_0_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Channels", msm_snd_enum[16], + msm_tert_tdm_rx_1_ch_get, msm_tert_tdm_rx_1_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Channels", msm_snd_enum[16], + msm_tert_tdm_rx_2_ch_get, msm_tert_tdm_rx_2_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Channels", msm_snd_enum[16], + msm_tert_tdm_rx_3_ch_get, msm_tert_tdm_rx_3_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", msm_snd_enum[16], + msm_tert_tdm_tx_0_ch_get, msm_tert_tdm_tx_0_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Channels", msm_snd_enum[16], + msm_tert_tdm_tx_1_ch_get, msm_tert_tdm_tx_1_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Channels", msm_snd_enum[16], + msm_tert_tdm_tx_2_ch_get, msm_tert_tdm_tx_2_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Channels", msm_snd_enum[16], + msm_tert_tdm_tx_3_ch_get, msm_tert_tdm_tx_3_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", msm_snd_enum[16], + msm_quat_tdm_rx_0_ch_get, msm_quat_tdm_rx_0_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Channels", msm_snd_enum[16], + msm_quat_tdm_rx_1_ch_get, msm_quat_tdm_rx_1_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Channels", msm_snd_enum[16], + msm_quat_tdm_rx_2_ch_get, msm_quat_tdm_rx_2_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Channels", msm_snd_enum[16], + msm_quat_tdm_rx_3_ch_get, msm_quat_tdm_rx_3_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", msm_snd_enum[16], + msm_quat_tdm_tx_0_ch_get, msm_quat_tdm_tx_0_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Channels", msm_snd_enum[16], + msm_quat_tdm_tx_1_ch_get, msm_quat_tdm_tx_1_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Channels", msm_snd_enum[16], + msm_quat_tdm_tx_2_ch_get, msm_quat_tdm_tx_2_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Channels", msm_snd_enum[16], + msm_quat_tdm_tx_3_ch_get, msm_quat_tdm_tx_3_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Bit Format", msm_snd_enum[17], + msm_pri_tdm_tx_0_bit_format_get, + msm_pri_tdm_tx_0_bit_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_1 Bit Format", msm_snd_enum[17], + msm_pri_tdm_tx_1_bit_format_get, + msm_pri_tdm_tx_1_bit_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_2 Bit Format", msm_snd_enum[17], + msm_pri_tdm_tx_2_bit_format_get, + msm_pri_tdm_tx_2_bit_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_3 Bit Format", msm_snd_enum[17], + msm_pri_tdm_tx_3_bit_format_get, + msm_pri_tdm_tx_3_bit_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Bit Format", msm_snd_enum[17], + msm_pri_tdm_rx_0_bit_format_get, + msm_pri_tdm_rx_0_bit_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_1 Bit Format", msm_snd_enum[17], + msm_pri_tdm_rx_1_bit_format_get, + msm_pri_tdm_rx_1_bit_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_2 Bit Format", msm_snd_enum[17], + msm_pri_tdm_rx_2_bit_format_get, + msm_pri_tdm_rx_2_bit_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_3 Bit Format", msm_snd_enum[17], + msm_pri_tdm_rx_3_bit_format_get, + msm_pri_tdm_rx_3_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Bit Format", msm_snd_enum[17], + msm_sec_tdm_rx_0_bit_format_get, + msm_sec_tdm_rx_0_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_1 Bit Format", msm_snd_enum[17], + msm_sec_tdm_rx_1_bit_format_get, + msm_sec_tdm_rx_1_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_2 Bit Format", msm_snd_enum[17], + msm_sec_tdm_rx_2_bit_format_get, + msm_sec_tdm_rx_2_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_3 Bit Format", msm_snd_enum[17], + msm_sec_tdm_rx_3_bit_format_get, + msm_sec_tdm_rx_3_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Bit Format", msm_snd_enum[17], + msm_sec_tdm_tx_0_bit_format_get, + msm_sec_tdm_tx_0_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_1 Bit Format", msm_snd_enum[17], + msm_sec_tdm_tx_1_bit_format_get, + msm_sec_tdm_tx_1_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_2 Bit Format", msm_snd_enum[17], + msm_sec_tdm_tx_2_bit_format_get, + msm_sec_tdm_tx_2_bit_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_3 Bit Format", msm_snd_enum[17], + msm_sec_tdm_tx_3_bit_format_get, + msm_sec_tdm_tx_3_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Bit Format", msm_snd_enum[17], + msm_tert_tdm_rx_0_bit_format_get, + msm_tert_tdm_rx_0_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_1 Bit Format", msm_snd_enum[17], + msm_tert_tdm_rx_1_bit_format_get, + msm_tert_tdm_rx_1_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_2 Bit Format", msm_snd_enum[17], + msm_tert_tdm_rx_2_bit_format_get, + msm_tert_tdm_rx_2_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_3 Bit Format", msm_snd_enum[17], + msm_tert_tdm_rx_3_bit_format_get, + msm_tert_tdm_rx_3_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Bit Format", msm_snd_enum[17], + msm_tert_tdm_tx_0_bit_format_get, + msm_tert_tdm_tx_0_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_1 Bit Format", msm_snd_enum[17], + msm_tert_tdm_tx_1_bit_format_get, + msm_tert_tdm_tx_1_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_2 Bit Format", msm_snd_enum[17], + msm_tert_tdm_tx_2_bit_format_get, + msm_tert_tdm_tx_2_bit_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_3 Bit Format", msm_snd_enum[17], + msm_tert_tdm_tx_3_bit_format_get, + msm_tert_tdm_tx_3_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Bit Format", msm_snd_enum[17], + msm_quat_tdm_rx_0_bit_format_get, + msm_quat_tdm_rx_0_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_1 Bit Format", msm_snd_enum[17], + msm_quat_tdm_rx_1_bit_format_get, + msm_quat_tdm_rx_1_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_2 Bit Format", msm_snd_enum[17], + msm_quat_tdm_rx_2_bit_format_get, + msm_quat_tdm_rx_2_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_3 Bit Format", msm_snd_enum[17], + msm_quat_tdm_rx_3_bit_format_get, + msm_quat_tdm_rx_3_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Bit Format", msm_snd_enum[17], + msm_quat_tdm_tx_0_bit_format_get, + msm_quat_tdm_tx_0_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_1 Bit Format", msm_snd_enum[17], + msm_quat_tdm_tx_1_bit_format_get, + msm_quat_tdm_tx_1_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_2 Bit Format", msm_snd_enum[17], + msm_quat_tdm_tx_2_bit_format_get, + msm_quat_tdm_tx_2_bit_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_3 Bit Format", msm_snd_enum[17], + msm_quat_tdm_tx_3_bit_format_get, + msm_quat_tdm_tx_3_bit_format_put), + SOC_ENUM_EXT("PRI_TDM SampleRate", msm_snd_enum[18], + msm_pri_tdm_rate_get, msm_pri_tdm_rate_put), + SOC_ENUM_EXT("PRI_TDM Slot Number", msm_snd_enum[19], + msm_pri_tdm_slot_num_get, msm_pri_tdm_slot_num_put), + SOC_ENUM_EXT("PRI_TDM Slot Width", msm_snd_enum[20], + msm_pri_tdm_slot_width_get, msm_pri_tdm_slot_width_put), + SOC_ENUM_EXT("SEC_TDM SampleRate", msm_snd_enum[18], + msm_sec_tdm_rate_get, msm_sec_tdm_rate_put), + SOC_ENUM_EXT("SEC_TDM Slot Number", msm_snd_enum[19], + msm_sec_tdm_slot_num_get, msm_sec_tdm_slot_num_put), + SOC_ENUM_EXT("SEC_TDM Slot Width", msm_snd_enum[20], + msm_sec_tdm_slot_width_get, msm_sec_tdm_slot_width_put), + SOC_ENUM_EXT("TERT_TDM SampleRate", msm_snd_enum[18], + msm_tert_tdm_rate_get, msm_tert_tdm_rate_put), + SOC_ENUM_EXT("TERT_TDM Slot Number", msm_snd_enum[19], + msm_tert_tdm_slot_num_get, msm_tert_tdm_slot_num_put), + SOC_ENUM_EXT("TERT_TDM Slot Width", msm_snd_enum[20], + msm_tert_tdm_slot_width_get, + msm_tert_tdm_slot_width_put), + SOC_ENUM_EXT("QUAT_TDM SampleRate", msm_snd_enum[18], + msm_quat_tdm_rate_get, msm_quat_tdm_rate_put), + SOC_ENUM_EXT("QUAT_TDM Slot Number", msm_snd_enum[19], + msm_quat_tdm_slot_num_get, msm_quat_tdm_slot_num_put), + SOC_ENUM_EXT("QUAT_TDM Slot Width", msm_snd_enum[20], + msm_quat_tdm_slot_width_get, + msm_quat_tdm_slot_width_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_4 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_5 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_6 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_7 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_RX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_4 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_5 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_6 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_7 Slot Mapping", SND_SOC_NOPM, + PRIMARY_TDM_TX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_4 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_5 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_6 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_7 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_RX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_4 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_5 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_6 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_7 Slot Mapping", SND_SOC_NOPM, + SECONDARY_TDM_TX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_5 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_6 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_7 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_RX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_4 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_5 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_6 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_7 Slot Mapping", SND_SOC_NOPM, + TERTIARY_TDM_TX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_4 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_5 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_6 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_7 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_RX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_0, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_1, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_2, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_3, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_4 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_4, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_5 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_5, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_6 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_6, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), + SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_7 Slot Mapping", SND_SOC_NOPM, + QUATERNARY_TDM_TX_7, 0xFFFF, + 0, 8, msm_tdm_slot_mapping_get, + msm_tdm_slot_mapping_put), }; static bool msm8996_swap_gnd_mic(struct snd_soc_codec *codec) @@ -2016,10 +5965,8 @@ static void *def_tasha_mbhc_cal(void) tasha_wcd_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS, WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL); - if (!tasha_wcd_cal) { - pr_err("%s: out of memory\n", __func__); + 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); @@ -2060,7 +6007,7 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream, 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); + &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); @@ -2079,7 +6026,7 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream, msm_slim_0_rx_ch); rx_ch_count = msm_slim_0_rx_ch; } - ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0, + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, rx_ch_count, rx_ch); if (ret < 0) { pr_err("%s: failed to set cpu chan map, err:%d\n", @@ -2091,7 +6038,7 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream, 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); + &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); @@ -2119,7 +6066,8 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream, tx_ch_cnt, dai_link->be_id); ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0 , 0); + user_set_tx_ch, + tx_ch, 0, NULL); if (ret < 0) { pr_err("%s: failed to set cpu chan map, err:%d\n", __func__, ret); @@ -2153,7 +6101,7 @@ static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, 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); + &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); @@ -2166,7 +6114,7 @@ static int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, __func__, tx_ch_cnt, dai_link->be_id); ret = snd_soc_dai_set_channel_map(cpu_dai, - user_set_tx_ch, tx_ch, 0 , 0); + user_set_tx_ch, tx_ch, 0, NULL); if (ret < 0) pr_err("%s: failed to set cpu chan map, err:%d\n", __func__, ret); @@ -2199,13 +6147,13 @@ static int msm8996_slimbus_2_hw_params(struct snd_pcm_substream *substream, 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); + &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, + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, num_rx_ch, rx_ch); if (ret < 0) { pr_err("%s: failed to set cpu chan map, err:%d\n", @@ -2217,14 +6165,14 @@ static int msm8996_slimbus_2_hw_params(struct snd_pcm_substream *substream, 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); + &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); + num_tx_ch, tx_ch, 0, NULL); if (ret < 0) { pr_err("%s: failed to set cpu chan map, err:%d\n", __func__, ret); @@ -2963,7 +6911,489 @@ static struct snd_soc_dai_link msm8996_common_dai_links[] = { .be_id = MSM_FRONTEND_DAI_VOICE2, }, }; +static struct snd_soc_dai_link msm8996_tdm_fe_dai_links[] = { + { + .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 RX 1 Hostless", + .stream_name = "Primary TDM RX 1 Hostless", + .cpu_dai_name = "PRI_TDM_RX_1_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 RX 2 Hostless", + .stream_name = "Primary TDM RX 2 Hostless", + .cpu_dai_name = "PRI_TDM_RX_2_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 RX 3 Hostless", + .stream_name = "Primary TDM RX 3 Hostless", + .cpu_dai_name = "PRI_TDM_RX_3_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 = "Primary TDM TX 1 Hostless", + .stream_name = "Primary TDM TX 1 Hostless", + .cpu_dai_name = "PRI_TDM_TX_1_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 = "Primary TDM TX 2 Hostless", + .stream_name = "Primary TDM TX 2 Hostless", + .cpu_dai_name = "PRI_TDM_TX_2_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 = "Primary TDM TX 3 Hostless", + .stream_name = "Primary TDM TX 3 Hostless", + .cpu_dai_name = "PRI_TDM_TX_3_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 RX 1 Hostless", + .stream_name = "Secondary TDM RX 1 Hostless", + .cpu_dai_name = "SEC_TDM_RX_1_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 RX 2 Hostless", + .stream_name = "Secondary TDM RX 2 Hostless", + .cpu_dai_name = "SEC_TDM_RX_2_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 RX 3 Hostless", + .stream_name = "Secondary TDM RX 3 Hostless", + .cpu_dai_name = "SEC_TDM_RX_3_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 = "Secondary TDM TX 1 Hostless", + .stream_name = "Secondary TDM TX 1 Hostless", + .cpu_dai_name = "SEC_TDM_TX_1_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 TX 2 Hostless", + .stream_name = "Secondary TDM TX 2 Hostless", + .cpu_dai_name = "SEC_TDM_TX_2_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 TX 3 Hostless", + .stream_name = "Secondary TDM TX 3 Hostless", + .cpu_dai_name = "SEC_TDM_TX_3_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 RX 1 Hostless", + .stream_name = "Tertiary TDM RX 1 Hostless", + .cpu_dai_name = "TERT_TDM_RX_1_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 RX 2 Hostless", + .stream_name = "Tertiary TDM RX 2 Hostless", + .cpu_dai_name = "TERT_TDM_RX_2_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 RX 3 Hostless", + .stream_name = "Tertiary TDM RX 3 Hostless", + .cpu_dai_name = "TERT_TDM_RX_3_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 = "Tertiary TDM TX 1 Hostless", + .stream_name = "Tertiary TDM TX 1 Hostless", + .cpu_dai_name = "TERT_TDM_TX_1_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 TX 2 Hostless", + .stream_name = "Tertiary TDM TX 2 Hostless", + .cpu_dai_name = "TERT_TDM_TX_2_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 TX 3 Hostless", + .stream_name = "Tertiary TDM TX 3 Hostless", + .cpu_dai_name = "TERT_TDM_TX_3_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 RX 1 Hostless", + .stream_name = "Quaternary TDM RX 1 Hostless", + .cpu_dai_name = "QUAT_TDM_RX_1_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 RX 2 Hostless", + .stream_name = "Quaternary TDM RX 2 Hostless", + .cpu_dai_name = "QUAT_TDM_RX_2_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 RX 3 Hostless", + .stream_name = "Quaternary TDM RX 3 Hostless", + .cpu_dai_name = "QUAT_TDM_RX_3_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 TDM TX 1 Hostless", + .stream_name = "Quaternary TDM TX 1 Hostless", + .cpu_dai_name = "QUAT_TDM_TX_1_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 TX 2 Hostless", + .stream_name = "Quaternary TDM TX 2 Hostless", + .cpu_dai_name = "QUAT_TDM_TX_2_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 TX 3 Hostless", + .stream_name = "Quaternary TDM TX 3 Hostless", + .cpu_dai_name = "QUAT_TDM_TX_3_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 msm8996_tasha_fe_dai_links[] = { { .name = LPASS_BE_SLIMBUS_4_TX, @@ -3178,6 +7608,33 @@ static struct snd_soc_dai_link msm8996_common_be_dai_links[] = { .be_hw_params_fixup = msm_tx_be_hw_params_fixup, .ops = &msm8996_mi2s_be_ops, .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_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_be_hw_params_fixup, + .ignore_suspend = 1, } }; @@ -3336,7 +7793,458 @@ static struct snd_soc_dai_link msm8996_tasha_be_dai_links[] = { /* dai link has playback support */ .ignore_pmdown_time = 1, .ignore_suspend = 1, + } +}; +static struct snd_soc_dai_link msm8996_tdm_be_dai_links[] = { + { + .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_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_tdm_be_ops, + .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_tdm_be_hw_params_fixup, + .ops = &msm8996_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .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, + .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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-rx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_1, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_2, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_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, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_3, + .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, + .ops = &msm8996_tdm_be_ops, + .ignore_suspend = 1, + } + }; static struct snd_soc_dai_link msm8996_hdmi_dai_link[] = { @@ -3360,8 +8268,10 @@ static struct snd_soc_dai_link msm8996_hdmi_dai_link[] = { 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_tdm_fe_dai_links) + ARRAY_SIZE(msm8996_common_be_dai_links) + ARRAY_SIZE(msm8996_tasha_be_dai_links) + + ARRAY_SIZE(msm8996_tdm_be_dai_links) + ARRAY_SIZE(msm8996_hdmi_dai_link)]; static int msm8996_wsa881x_init(struct snd_soc_component *component) @@ -3564,8 +8474,8 @@ static const struct of_device_id msm8996_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, len_3, len_4; + struct snd_soc_dai_link *dailink = NULL; + int len_1 = 0, len_2 = 0, len_3 = 0, len_4 = 0, len_5 = 0; const struct of_device_id *match; match = of_match_node(msm8996_asoc_machine_of_match, dev->of_node); @@ -3579,7 +8489,8 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) 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); + len_3 = len_2 + ARRAY_SIZE(msm8996_tdm_fe_dai_links); + len_4 = len_3 + ARRAY_SIZE(msm8996_common_be_dai_links); memcpy(msm8996_tasha_dai_links, msm8996_common_dai_links, @@ -3588,29 +8499,40 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) msm8996_tasha_fe_dai_links, sizeof(msm8996_tasha_fe_dai_links)); memcpy(msm8996_tasha_dai_links + len_2, + msm8996_tdm_fe_dai_links, + sizeof(msm8996_tdm_fe_dai_links)); + memcpy(msm8996_tasha_dai_links + len_3, msm8996_common_be_dai_links, sizeof(msm8996_common_be_dai_links)); - memcpy(msm8996_tasha_dai_links + len_3, + memcpy(msm8996_tasha_dai_links + len_4, 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); + len_5 = len_4 + 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, + memcpy(dailink + len_5, msm8996_hdmi_dai_link, sizeof(msm8996_hdmi_dai_link)); - len_4 += ARRAY_SIZE(msm8996_hdmi_dai_link); + len_5 += ARRAY_SIZE(msm8996_hdmi_dai_link); } else { dev_dbg(dev, "%s(): No hdmi audio support\n", __func__); } - + if (of_property_read_bool(dev->of_node, "qcom,tdm-audio-intf")) { + dev_dbg(dev, "%s(): TDM support present\n", + __func__); + memcpy(dailink + len_5, msm8996_tdm_be_dai_links, + sizeof(msm8996_tdm_be_dai_links)); + len_5 += ARRAY_SIZE(msm8996_tdm_be_dai_links); + } else { + dev_dbg(dev, "%s(): No TDM support\n", __func__); + } if (card) { card->dai_link = dailink; - card->num_links = len_4; + card->num_links = len_5; } return card; diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 7e22567ead96..45a3f42b6f55 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -105,6 +105,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]; int32_t ion_fd[MSM_FRONTEND_DAI_MAX]; + bool is_in_use[MSM_FRONTEND_DAI_MAX]; }; struct msm_compr_audio { @@ -1574,12 +1575,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 msm_compr_audio *prtd; + struct msm_compr_audio *prtd = NULL; struct msm_compr_pdata *pdata = snd_soc_platform_get_drvdata(rtd->platform); int ret = 0; pr_debug("%s\n", __func__); + if (pdata->is_in_use[rtd->dai_link->be_id] == true) { + pr_err("%s: %s is already in use,err: %d ", + __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"); @@ -1591,14 +1597,14 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) pdata->cstream[rtd->dai_link->be_id] = cstream; pdata->audio_effects[rtd->dai_link->be_id] = kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL); - if (!pdata->audio_effects[rtd->dai_link->be_id]) { + if (pdata->audio_effects[rtd->dai_link->be_id] == NULL) { pr_err("%s: Could not allocate memory for effects\n", __func__); ret = -ENOMEM; goto effect_err; } pdata->dec_params[rtd->dai_link->be_id] = kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL); - if (!pdata->dec_params[rtd->dai_link->be_id]) { + if (pdata->dec_params[rtd->dai_link->be_id] == NULL) { pr_err("%s: Could not allocate memory for dec params\n", __func__); ret = -ENOMEM; @@ -1659,14 +1665,17 @@ static int msm_compr_playback_open(struct snd_compr_stream *cstream) if (ret < 0) goto map_err; } + pdata->is_in_use[rtd->dai_link->be_id] = true; return 0; map_err: q6asm_audio_client_free(prtd->audio_client); ac_err: kfree(pdata->dec_params[rtd->dai_link->be_id]); + pdata->dec_params[rtd->dai_link->be_id] = NULL; param_err: kfree(pdata->audio_effects[rtd->dai_link->be_id]); + pdata->audio_effects[rtd->dai_link->be_id] = NULL; effect_err: pdata->cstream[rtd->dai_link->be_id] = NULL; runtime->private_data = NULL; @@ -1836,10 +1845,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); + if (pdata->audio_effects[soc_prtd->dai_link->be_id] != NULL) { kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]); pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL; + } + if (pdata->dec_params[soc_prtd->dai_link->be_id] != NULL) { kfree(pdata->dec_params[soc_prtd->dai_link->be_id]); pdata->dec_params[soc_prtd->dai_link->be_id] = NULL; + } + pdata->is_in_use[soc_prtd->dai_link->be_id] = false; kfree(prtd); runtime->private_data = NULL; @@ -4038,6 +4052,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, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c index 0d01803e634d..7e022619c097 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c @@ -183,6 +183,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]; diff --git a/sound/soc/msm/sdm660-common.h b/sound/soc/msm/sdm660-common.h index bca8cd788a39..549c3879d1af 100644 --- a/sound/soc/msm/sdm660-common.h +++ b/sound/soc/msm/sdm660-common.h @@ -17,6 +17,9 @@ #include <sound/q6afe-v2.h> #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/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c index 948fb287023d..3d86abd6964f 100644 --- a/sound/soc/msm/sdm660-internal.c +++ b/sound/soc/msm/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) @@ -2975,6 +2961,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); |
