|
@@ -131,6 +131,15 @@ enum {
|
|
|
CDC_DMA_TX_MAX,
|
|
|
};
|
|
|
|
|
|
+enum {
|
|
|
+ SLIM_RX_7 = 0,
|
|
|
+ SLIM_RX_MAX,
|
|
|
+};
|
|
|
+enum {
|
|
|
+ SLIM_TX_7 = 0,
|
|
|
+ SLIM_TX_MAX,
|
|
|
+};
|
|
|
+
|
|
|
struct msm_asoc_mach_data {
|
|
|
struct snd_info_entry *codec_root;
|
|
|
int usbc_en2_gpio; /* used by gpio driver API */
|
|
@@ -171,6 +180,15 @@ struct dev_config {
|
|
|
u32 channels;
|
|
|
};
|
|
|
|
|
|
+/* Default configuration of slimbus channels */
|
|
|
+static struct dev_config slim_rx_cfg[] = {
|
|
|
+ [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
|
|
+};
|
|
|
+
|
|
|
+static struct dev_config slim_tx_cfg[] = {
|
|
|
+ [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
|
|
|
+};
|
|
|
+
|
|
|
/* Default configuration of external display BE */
|
|
|
static struct dev_config ext_disp_rx_cfg[] = {
|
|
|
[EXT_DISP_RX_IDX_DP] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
|
|
@@ -393,6 +411,15 @@ static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE",
|
|
|
static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96",
|
|
|
"KHZ_192", "KHZ_32", "KHZ_44P1",
|
|
|
"KHZ_88P2", "KHZ_176P4"};
|
|
|
+static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16",
|
|
|
+ "KHZ_44P1", "KHZ_48",
|
|
|
+ "KHZ_88P2", "KHZ_96"};
|
|
|
+static char const *bt_sample_rate_rx_text[] = {"KHZ_8", "KHZ_16",
|
|
|
+ "KHZ_44P1", "KHZ_48",
|
|
|
+ "KHZ_88P2", "KHZ_96"};
|
|
|
+static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16",
|
|
|
+ "KHZ_44P1", "KHZ_48",
|
|
|
+ "KHZ_88P2", "KHZ_96"};
|
|
|
|
|
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
|
|
|
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
|
|
@@ -496,6 +523,9 @@ static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text);
|
|
|
static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text);
|
|
|
static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate,
|
|
|
ext_disp_sample_rate_text);
|
|
|
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
|
|
|
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text);
|
|
|
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text);
|
|
|
|
|
|
static bool is_initial_boot;
|
|
|
static bool codec_reg_done;
|
|
@@ -2783,6 +2813,204 @@ static int msm_cdc_dma_get_idx_from_beid(int32_t be_id)
|
|
|
return idx;
|
|
|
}
|
|
|
|
|
|
+static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
|
|
|
+ * when used for BT_SCO use case. Return either Rx or Tx sample rate
|
|
|
+ * value.
|
|
|
+ */
|
|
|
+ switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
|
|
|
+ case SAMPLING_RATE_96KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 5;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_88P2KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 4;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_48KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 3;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_44P1KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 2;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_16KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 1;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_8KHZ:
|
|
|
+ default:
|
|
|
+ ucontrol->value.integer.value[0] = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pr_debug("%s: sample rate = %d\n", __func__,
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
|
+{
|
|
|
+ switch (ucontrol->value.integer.value[0]) {
|
|
|
+ case 1:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
|
|
|
+ break;
|
|
|
+ case 0:
|
|
|
+ default:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n",
|
|
|
+ __func__,
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate,
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate,
|
|
|
+ ucontrol->value.enumerated.item[0]);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int msm_bt_sample_rate_rx_get(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
|
+{
|
|
|
+ switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
|
|
|
+ case SAMPLING_RATE_96KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 5;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_88P2KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 4;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_48KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 3;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_44P1KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 2;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_16KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 1;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_8KHZ:
|
|
|
+ default:
|
|
|
+ ucontrol->value.integer.value[0] = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pr_debug("%s: sample rate rx = %d\n", __func__,
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int msm_bt_sample_rate_rx_put(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
|
+{
|
|
|
+ switch (ucontrol->value.integer.value[0]) {
|
|
|
+ case 1:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
|
|
|
+ break;
|
|
|
+ case 0:
|
|
|
+ default:
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pr_debug("%s: sample rate: slim7_rx = %d, value = %d\n",
|
|
|
+ __func__,
|
|
|
+ slim_rx_cfg[SLIM_RX_7].sample_rate,
|
|
|
+ ucontrol->value.enumerated.item[0]);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int msm_bt_sample_rate_tx_get(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
|
+{
|
|
|
+ switch (slim_tx_cfg[SLIM_TX_7].sample_rate) {
|
|
|
+ case SAMPLING_RATE_96KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 5;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_88P2KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 4;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_48KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 3;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_44P1KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 2;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_16KHZ:
|
|
|
+ ucontrol->value.integer.value[0] = 1;
|
|
|
+ break;
|
|
|
+ case SAMPLING_RATE_8KHZ:
|
|
|
+ default:
|
|
|
+ ucontrol->value.integer.value[0] = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pr_debug("%s: sample rate tx = %d\n", __func__,
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
|
+{
|
|
|
+ switch (ucontrol->value.integer.value[0]) {
|
|
|
+ case 1:
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
|
|
|
+ break;
|
|
|
+ case 0:
|
|
|
+ default:
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pr_debug("%s: sample rate: slim7_tx = %d, value = %d\n",
|
|
|
+ __func__,
|
|
|
+ slim_tx_cfg[SLIM_TX_7].sample_rate,
|
|
|
+ ucontrol->value.enumerated.item[0]);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static const struct snd_kcontrol_new msm_int_snd_controls[] = {
|
|
|
SOC_ENUM_EXT("WSA_CDC_DMA_RX_0 Channels", wsa_cdc_dma_rx_0_chs,
|
|
|
cdc_dma_rx_ch_get, cdc_dma_rx_ch_put),
|
|
@@ -3062,6 +3290,15 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = {
|
|
|
SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate,
|
|
|
ext_disp_rx_sample_rate_get,
|
|
|
ext_disp_rx_sample_rate_put),
|
|
|
+ SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
|
|
|
+ msm_bt_sample_rate_get,
|
|
|
+ msm_bt_sample_rate_put),
|
|
|
+ SOC_ENUM_EXT("BT SampleRate RX", bt_sample_rate_rx,
|
|
|
+ msm_bt_sample_rate_rx_get,
|
|
|
+ msm_bt_sample_rate_rx_put),
|
|
|
+ SOC_ENUM_EXT("BT SampleRate TX", bt_sample_rate_tx,
|
|
|
+ msm_bt_sample_rate_tx_get,
|
|
|
+ msm_bt_sample_rate_tx_put),
|
|
|
};
|
|
|
|
|
|
static const struct snd_kcontrol_new msm_snd_controls[] = {
|
|
@@ -3327,6 +3564,20 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
|
|
channels->min = channels->max = msm_vi_feed_tx_ch;
|
|
|
break;
|
|
|
|
|
|
+ case MSM_BACKEND_DAI_SLIMBUS_7_RX:
|
|
|
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
|
|
|
+ slim_rx_cfg[SLIM_RX_7].bit_format);
|
|
|
+ rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate;
|
|
|
+ channels->min = channels->max =
|
|
|
+ slim_rx_cfg[SLIM_RX_7].channels;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case MSM_BACKEND_DAI_SLIMBUS_7_TX:
|
|
|
+ rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate;
|
|
|
+ channels->min = channels->max =
|
|
|
+ slim_tx_cfg[SLIM_TX_7].channels;
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
rate->min = rate->max = SAMPLING_RATE_48KHZ;
|
|
|
break;
|