Loading asoc/msm-compress-q6-v2.c +43 −16 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include <dsp/msm_audio_ion.h> #include <dsp/apr_audio-v2.h> #include <dsp/q6asm-v2.h> #include <dsp/q6core.h> #include <dsp/msm-audio-effects-q6-v2.h> #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" Loading Loading @@ -204,7 +205,7 @@ struct msm_compr_dec_params { struct msm_compr_ch_map { bool set_ch_map; char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; }; static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, Loading Loading @@ -1012,6 +1013,21 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, sample_word_size = 16; break; } if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) { ret = q6asm_media_format_block_pcm_format_support_v5( prtd->audio_client, prtd->sample_rate, prtd->num_channels, bit_width, stream_id, use_default_chmap, chmap, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } else { ret = q6asm_media_format_block_pcm_format_support_v4( prtd->audio_client, prtd->sample_rate, Loading @@ -1022,6 +1038,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } if (ret < 0) pr_err("%s: CMD Format block failed\n", __func__); Loading Loading @@ -1336,6 +1353,15 @@ static int msm_compr_configure_dsp_for_playback } else { pr_debug("%s: stream_id %d bits_per_sample %d\n", __func__, ac->stream_id, bits_per_sample); if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_stream_open_write_v5(ac, prtd->codec, bits_per_sample, ac->stream_id, prtd->gapless_state.use_dsp_gapless_mode); else ret = q6asm_stream_open_write_v4(ac, prtd->codec, bits_per_sample, ac->stream_id, Loading Loading @@ -3640,7 +3666,7 @@ static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, if (pdata->ch_map[fe_id]) { pdata->ch_map[fe_id]->set_ch_map = true; for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) pdata->ch_map[fe_id]->channel_map[i] = (char)(ucontrol->value.integer.value[i]); } else { Loading Loading @@ -3669,7 +3695,7 @@ static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol, goto end; } if (pdata->ch_map[fe_id]) { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = pdata->ch_map[fe_id]->channel_map[i]; } Loading Loading @@ -3983,9 +4009,10 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 8; uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0xFFFFFFFF; /* See PCM_CHANNEL_RSD=34 in apr_audio-v2.h */ uinfo->value.integer.max = 34; return 0; } Loading asoc/msm-dai-fe.c +3 −3 Original line number Diff line number Diff line Loading @@ -99,7 +99,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, .channels_max = 8, .channels_max = 16, .rate_min = 8000, .rate_max = 384000, }, Loading @@ -113,7 +113,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, .channels_max = 8, .channels_max = 16, .rate_min = 8000, .rate_max = 48000, }, Loading Loading @@ -311,7 +311,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, .channels_max = 8, .channels_max = 16, .rate_min = 8000, .rate_max = 384000, }, Loading asoc/msm-dai-q6-v2.c +278 −87 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #define CHANNEL_STATUS_MASK_INIT 0x0 #define CHANNEL_STATUS_MASK 0x4 #define AFE_API_VERSION_CLOCK_SET 1 #define MSM_DAI_SYSFS_ENTRY_MAX_LEN 64 #define DAI_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ Loading Loading @@ -218,6 +219,7 @@ struct msm_dai_q6_spdif_dai_data { u16 port_id; struct afe_spdif_port_config spdif_port; struct afe_event_fmt_update fmt_event; struct kobject *kobj; }; struct msm_dai_q6_spdif_event_msg { Loading Loading @@ -1459,39 +1461,6 @@ static int msm_dai_q6_spdif_source_get(struct snd_kcontrol *kcontrol, return 0; } static int msm_dai_q6_spdif_ext_state_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; ucontrol->value.integer.value[0] = dai_data->fmt_event.status & 0x3; return 0; } static int msm_dai_q6_spdif_ext_format_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; ucontrol->value.integer.value[0] = dai_data->fmt_event.data_format & 0x1; return 0; } static int msm_dai_q6_spdif_ext_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; ucontrol->value.integer.value[0] = dai_data->fmt_event.sample_rate; return 0; } static const char * const spdif_format[] = { "LPCM", "Compr" Loading @@ -1501,10 +1470,6 @@ static const char * const spdif_source[] = { "Optical", "EXT-ARC", "Coaxial", "VT-ARC" }; static const char * const spdif_state[] = { "Inactive", "Active", "EOS" }; static const struct soc_enum spdif_rx_config_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; Loading @@ -1514,11 +1479,6 @@ static const struct soc_enum spdif_tx_config_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; static const struct soc_enum spdif_tx_status_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_state), spdif_state), SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading Loading @@ -1609,21 +1569,6 @@ static const struct snd_kcontrol_new spdif_tx_config_controls[] = { msm_dai_q6_spdif_format_put) }; static const struct snd_kcontrol_new spdif_tx_status_controls[] = { SOC_ENUM_EXT("PRI SPDIF TX EXT State", spdif_tx_status_enum[0], msm_dai_q6_spdif_ext_state_get, NULL), SOC_ENUM_EXT("PRI SPDIF TX EXT Format", spdif_tx_status_enum[1], msm_dai_q6_spdif_ext_format_get, NULL), SOC_SINGLE_EXT("PRI SPDIF TX EXT Rate", 0, 0, 192000, 0, msm_dai_q6_spdif_ext_rate_get, NULL), SOC_ENUM_EXT("SEC SPDIF TX EXT State", spdif_tx_status_enum[0], msm_dai_q6_spdif_ext_state_get, NULL), SOC_ENUM_EXT("SEC SPDIF TX EXT Format", spdif_tx_status_enum[1], msm_dai_q6_spdif_ext_format_get, NULL), SOC_SINGLE_EXT("SEC SPDIF TX EXT Rate", 0, 0, 192000, 0, msm_dai_q6_spdif_ext_rate_get, NULL) }; static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token, uint32_t *payload, void *private_data) { Loading Loading @@ -1734,6 +1679,102 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream, return rc; } static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_state(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); if (!dai_data) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", dai_data->fmt_event.status); pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.status); return ret; } static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_format(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); if (!dai_data) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", dai_data->fmt_event.data_format); pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.data_format); return ret; } static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_rate(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); if (!dai_data) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", dai_data->fmt_event.sample_rate); pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.sample_rate); return ret; } static DEVICE_ATTR(audio_state, 0444, msm_dai_q6_spdif_sysfs_rda_audio_state, NULL); static DEVICE_ATTR(audio_format, 0444, msm_dai_q6_spdif_sysfs_rda_audio_format, NULL); static DEVICE_ATTR(audio_rate, 0444, msm_dai_q6_spdif_sysfs_rda_audio_rate, NULL); static struct attribute *msm_dai_q6_spdif_fs_attrs[] = { &dev_attr_audio_state.attr, &dev_attr_audio_format.attr, &dev_attr_audio_rate.attr, NULL, }; static struct attribute_group msm_dai_q6_spdif_fs_attrs_group = { .attrs = msm_dai_q6_spdif_fs_attrs, }; static int msm_dai_q6_spdif_sysfs_create(struct snd_soc_dai *dai, struct msm_dai_q6_spdif_dai_data *dai_data) { int rc; rc = sysfs_create_group(&dai->dev->kobj, &msm_dai_q6_spdif_fs_attrs_group); if (rc) { pr_err("%s: failed, rc=%d\n", __func__, rc); return rc; } dai_data->kobj = &dai->dev->kobj; return 0; } static void msm_dai_q6_spdif_sysfs_remove(struct snd_soc_dai *dai, struct msm_dai_q6_spdif_dai_data *dai_data) { if (dai_data->kobj) sysfs_remove_group(dai_data->kobj, &msm_dai_q6_spdif_fs_attrs_group); dai_data->kobj = NULL; } static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) { struct msm_dai_q6_spdif_dai_data *dai_data; Loading Loading @@ -1773,40 +1814,24 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) dai_data)); break; case AFE_PORT_ID_PRIMARY_SPDIF_TX: rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[0], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[1], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[0], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[1], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[2], dai_data)); break; case AFE_PORT_ID_SECONDARY_SPDIF_TX: rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[2], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[3], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[3], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[4], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[5], dai_data)); break; } if (rc < 0) Loading Loading @@ -1866,6 +1891,9 @@ static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai) clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } msm_dai_q6_spdif_sysfs_remove(dai, dai_data); kfree(dai_data); return 0; Loading Loading @@ -2095,7 +2123,7 @@ static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params, return 0; } static u8 num_of_bits_set(u8 sd_line_mask) static u16 num_of_bits_set(u16 sd_line_mask) { u8 num_bits_set = 0; Loading Loading @@ -4644,11 +4672,68 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, dai_data->channels = params_channels(params); switch (dai_data->channels) { case 15: case 16: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_16CHS; break; default: goto error_invalid_data; }; break; case 13: case 14: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_14CHS; break; default: goto error_invalid_data; }; break; case 11: case 12: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_12CHS: case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_12CHS; break; default: goto error_invalid_data; }; break; case 9: case 10: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_10CHS: case AFE_PORT_I2S_12CHS: case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_10CHS; break; default: goto error_invalid_data; }; break; case 8: case 7: if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS) goto error_invalid_data; dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS; else if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_8CHS_2) dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS_2; else dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS; break; case 6: case 5: Loading @@ -4658,15 +4743,34 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, break; case 4: case 3: if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01) switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_SD0: case AFE_PORT_I2S_SD1: case AFE_PORT_I2S_SD2: case AFE_PORT_I2S_SD3: case AFE_PORT_I2S_SD4: case AFE_PORT_I2S_SD5: case AFE_PORT_I2S_SD6: case AFE_PORT_I2S_SD7: goto error_invalid_data; if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23) break; case AFE_PORT_I2S_QUAD01: case AFE_PORT_I2S_QUAD23: case AFE_PORT_I2S_QUAD45: case AFE_PORT_I2S_QUAD67: dai_data->port_config.i2s.channel_mode = mi2s_dai_config->pdata_mi2s_lines; else break; case AFE_PORT_I2S_8CHS_2: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_QUAD45; break; default: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_QUAD01; break; }; break; case 2: case 1: if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_SD0) Loading @@ -4676,12 +4780,20 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_I2S_SD1: case AFE_PORT_I2S_SD2: case AFE_PORT_I2S_SD3: case AFE_PORT_I2S_SD4: case AFE_PORT_I2S_SD5: case AFE_PORT_I2S_SD6: case AFE_PORT_I2S_SD7: dai_data->port_config.i2s.channel_mode = mi2s_dai_config->pdata_mi2s_lines; break; case AFE_PORT_I2S_QUAD01: case AFE_PORT_I2S_6CHS: case AFE_PORT_I2S_8CHS: case AFE_PORT_I2S_10CHS: case AFE_PORT_I2S_12CHS: case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: if (dai_data->vi_feed_mono == SPKR_1) dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD0; Loading @@ -4693,6 +4805,14 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD2; break; case AFE_PORT_I2S_QUAD45: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD4; break; case AFE_PORT_I2S_QUAD67: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD6; break; } if (dai_data->channels == 2) dai_data->port_config.i2s.mono_stereo = Loading Loading @@ -4866,13 +4986,15 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | SNDRV_PCM_RATE_384000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE, .rate_min = 8000, .rate_max = 192000, .rate_max = 384000, }, .capture = { .stream_name = "Primary MI2S Capture", Loading Loading @@ -5257,6 +5379,18 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_SD3; break; case MSM_MI2S_SD4: *config_ptr = AFE_PORT_I2S_SD4; break; case MSM_MI2S_SD5: *config_ptr = AFE_PORT_I2S_SD5; break; case MSM_MI2S_SD6: *config_ptr = AFE_PORT_I2S_SD6; break; case MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_SD7; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); Loading @@ -5271,6 +5405,12 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD2 | MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_QUAD23; break; case MSM_MI2S_SD4 | MSM_MI2S_SD5: *config_ptr = AFE_PORT_I2S_QUAD45; break; case MSM_MI2S_SD6 | MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_QUAD67; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); Loading @@ -5293,6 +5433,57 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_8CHS; break; case MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_8CHS_2; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 5: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4: *config_ptr = AFE_PORT_I2S_10CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 6: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5: *config_ptr = AFE_PORT_I2S_12CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 7: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6: *config_ptr = AFE_PORT_I2S_14CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 8: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_16CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); Loading asoc/msm-dai-q6-v2.h +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,11 @@ #define MSM_MI2S_SD1 (1 << 1) #define MSM_MI2S_SD2 (1 << 2) #define MSM_MI2S_SD3 (1 << 3) #define MSM_MI2S_SD4 (1 << 4) #define MSM_MI2S_SD5 (1 << 5) #define MSM_MI2S_SD6 (1 << 6) #define MSM_MI2S_SD7 (1 << 7) #define MSM_MI2S_CAP_RX 0 #define MSM_MI2S_CAP_TX 1 Loading asoc/msm-pcm-q6-v2.c +60 −16 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ #include <sound/pcm_params.h> #include <dsp/msm_audio_ion.h> #include <dsp/q6audio-v2.h> #include <dsp/q6core.h> #include <dsp/q6asm-v2.h> #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" Loading Loading @@ -384,11 +386,17 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) return -ENOMEM; } } else { if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_open_write_v5(prtd->audio_client, fmt_type, bits_per_sample); else ret = q6asm_open_write_v4(prtd->audio_client, fmt_type, bits_per_sample); if (ret < 0) { pr_err("%s: q6asm_open_write_v4 failed (%d)\n", pr_err("%s: q6asm_open_write failed (%d)\n", __func__, ret); q6asm_audio_client_free(prtd->audio_client); prtd->audio_client = NULL; Loading Loading @@ -425,6 +433,18 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) runtime->channels, !prtd->set_channel_map, prtd->channel_map, bits_per_sample); } else { if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) { ret = q6asm_media_format_block_multi_ch_pcm_v5( prtd->audio_client, runtime->rate, runtime->channels, !prtd->set_channel_map, prtd->channel_map, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } else { ret = q6asm_media_format_block_multi_ch_pcm_v4( prtd->audio_client, runtime->rate, runtime->channels, !prtd->set_channel_map, Loading @@ -432,6 +452,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } } if (ret < 0) pr_info("%s: CMD Format block failed\n", __func__); Loading Loading @@ -489,7 +510,15 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) __func__, params_channels(params), prtd->audio_client->perf_mode); ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_open_read_v5(prtd->audio_client, FORMAT_LINEAR_PCM, bits_per_sample, false, ENC_CFG_ID_NONE); else ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, bits_per_sample, false, ENC_CFG_ID_NONE); if (ret < 0) { pr_err("%s: q6asm_open_read failed\n", __func__); Loading Loading @@ -557,13 +586,28 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n", __func__, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size); ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_enc_cfg_blk_pcm_format_support_v5( prtd->audio_client, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); else ret = q6asm_enc_cfg_blk_pcm_format_support_v4( prtd->audio_client, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); if (ret < 0) pr_debug("%s: cmd cfg pcm was block failed", __func__); Loading Loading @@ -1508,7 +1552,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, prtd = substream->runtime->private_data; if (prtd) { prtd->set_channel_map = true; for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) prtd->channel_map[i] = (char)(ucontrol->value.integer.value[i]); } Loading Loading @@ -1536,11 +1580,11 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, prtd = substream->runtime->private_data; if (prtd && prtd->set_channel_map == true) { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = (int)prtd->channel_map[i]; } else { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = 0; } Loading @@ -1558,7 +1602,7 @@ static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd) pr_debug("%s, Channel map cntrl add\n", __func__); ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_std_chmaps, PCM_FORMAT_MAX_NUM_CHANNEL, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, 0, &chmap_info); if (ret < 0) { pr_err("%s, channel map cntrl add failed\n", __func__); Loading Loading
asoc/msm-compress-q6-v2.c +43 −16 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #include <dsp/msm_audio_ion.h> #include <dsp/apr_audio-v2.h> #include <dsp/q6asm-v2.h> #include <dsp/q6core.h> #include <dsp/msm-audio-effects-q6-v2.h> #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" Loading Loading @@ -204,7 +205,7 @@ struct msm_compr_dec_params { struct msm_compr_ch_map { bool set_ch_map; char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL]; char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL_V8]; }; static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, Loading Loading @@ -1012,6 +1013,21 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, sample_word_size = 16; break; } if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) { ret = q6asm_media_format_block_pcm_format_support_v5( prtd->audio_client, prtd->sample_rate, prtd->num_channels, bit_width, stream_id, use_default_chmap, chmap, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } else { ret = q6asm_media_format_block_pcm_format_support_v4( prtd->audio_client, prtd->sample_rate, Loading @@ -1022,6 +1038,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } if (ret < 0) pr_err("%s: CMD Format block failed\n", __func__); Loading Loading @@ -1336,6 +1353,15 @@ static int msm_compr_configure_dsp_for_playback } else { pr_debug("%s: stream_id %d bits_per_sample %d\n", __func__, ac->stream_id, bits_per_sample); if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_stream_open_write_v5(ac, prtd->codec, bits_per_sample, ac->stream_id, prtd->gapless_state.use_dsp_gapless_mode); else ret = q6asm_stream_open_write_v4(ac, prtd->codec, bits_per_sample, ac->stream_id, Loading Loading @@ -3640,7 +3666,7 @@ static int msm_compr_channel_map_put(struct snd_kcontrol *kcontrol, if (pdata->ch_map[fe_id]) { pdata->ch_map[fe_id]->set_ch_map = true; for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) pdata->ch_map[fe_id]->channel_map[i] = (char)(ucontrol->value.integer.value[i]); } else { Loading Loading @@ -3669,7 +3695,7 @@ static int msm_compr_channel_map_get(struct snd_kcontrol *kcontrol, goto end; } if (pdata->ch_map[fe_id]) { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = pdata->ch_map[fe_id]->channel_map[i]; } Loading Loading @@ -3983,9 +4009,10 @@ static int msm_compr_channel_map_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 8; uinfo->count = PCM_FORMAT_MAX_NUM_CHANNEL_V8; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0xFFFFFFFF; /* See PCM_CHANNEL_RSD=34 in apr_audio-v2.h */ uinfo->value.integer.max = 34; return 0; } Loading
asoc/msm-dai-fe.c +3 −3 Original line number Diff line number Diff line Loading @@ -99,7 +99,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, .channels_max = 8, .channels_max = 16, .rate_min = 8000, .rate_max = 384000, }, Loading @@ -113,7 +113,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, .channels_max = 8, .channels_max = 16, .rate_min = 8000, .rate_max = 48000, }, Loading Loading @@ -311,7 +311,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE), .channels_min = 1, .channels_max = 8, .channels_max = 16, .rate_min = 8000, .rate_max = 384000, }, Loading
asoc/msm-dai-q6-v2.c +278 −87 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #define CHANNEL_STATUS_MASK_INIT 0x0 #define CHANNEL_STATUS_MASK 0x4 #define AFE_API_VERSION_CLOCK_SET 1 #define MSM_DAI_SYSFS_ENTRY_MAX_LEN 64 #define DAI_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \ Loading Loading @@ -218,6 +219,7 @@ struct msm_dai_q6_spdif_dai_data { u16 port_id; struct afe_spdif_port_config spdif_port; struct afe_event_fmt_update fmt_event; struct kobject *kobj; }; struct msm_dai_q6_spdif_event_msg { Loading Loading @@ -1459,39 +1461,6 @@ static int msm_dai_q6_spdif_source_get(struct snd_kcontrol *kcontrol, return 0; } static int msm_dai_q6_spdif_ext_state_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; ucontrol->value.integer.value[0] = dai_data->fmt_event.status & 0x3; return 0; } static int msm_dai_q6_spdif_ext_format_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; ucontrol->value.integer.value[0] = dai_data->fmt_event.data_format & 0x1; return 0; } static int msm_dai_q6_spdif_ext_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data; ucontrol->value.integer.value[0] = dai_data->fmt_event.sample_rate; return 0; } static const char * const spdif_format[] = { "LPCM", "Compr" Loading @@ -1501,10 +1470,6 @@ static const char * const spdif_source[] = { "Optical", "EXT-ARC", "Coaxial", "VT-ARC" }; static const char * const spdif_state[] = { "Inactive", "Active", "EOS" }; static const struct soc_enum spdif_rx_config_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; Loading @@ -1514,11 +1479,6 @@ static const struct soc_enum spdif_tx_config_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; static const struct soc_enum spdif_tx_status_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_state), spdif_state), SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format), }; static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { Loading Loading @@ -1609,21 +1569,6 @@ static const struct snd_kcontrol_new spdif_tx_config_controls[] = { msm_dai_q6_spdif_format_put) }; static const struct snd_kcontrol_new spdif_tx_status_controls[] = { SOC_ENUM_EXT("PRI SPDIF TX EXT State", spdif_tx_status_enum[0], msm_dai_q6_spdif_ext_state_get, NULL), SOC_ENUM_EXT("PRI SPDIF TX EXT Format", spdif_tx_status_enum[1], msm_dai_q6_spdif_ext_format_get, NULL), SOC_SINGLE_EXT("PRI SPDIF TX EXT Rate", 0, 0, 192000, 0, msm_dai_q6_spdif_ext_rate_get, NULL), SOC_ENUM_EXT("SEC SPDIF TX EXT State", spdif_tx_status_enum[0], msm_dai_q6_spdif_ext_state_get, NULL), SOC_ENUM_EXT("SEC SPDIF TX EXT Format", spdif_tx_status_enum[1], msm_dai_q6_spdif_ext_format_get, NULL), SOC_SINGLE_EXT("SEC SPDIF TX EXT Rate", 0, 0, 192000, 0, msm_dai_q6_spdif_ext_rate_get, NULL) }; static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token, uint32_t *payload, void *private_data) { Loading Loading @@ -1734,6 +1679,102 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream, return rc; } static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_state(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); if (!dai_data) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", dai_data->fmt_event.status); pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.status); return ret; } static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_format(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); if (!dai_data) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", dai_data->fmt_event.data_format); pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.data_format); return ret; } static ssize_t msm_dai_q6_spdif_sysfs_rda_audio_rate(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dev); if (!dai_data) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } ret = snprintf(buf, MSM_DAI_SYSFS_ENTRY_MAX_LEN, "%d\n", dai_data->fmt_event.sample_rate); pr_debug("%s: '%d'\n", __func__, dai_data->fmt_event.sample_rate); return ret; } static DEVICE_ATTR(audio_state, 0444, msm_dai_q6_spdif_sysfs_rda_audio_state, NULL); static DEVICE_ATTR(audio_format, 0444, msm_dai_q6_spdif_sysfs_rda_audio_format, NULL); static DEVICE_ATTR(audio_rate, 0444, msm_dai_q6_spdif_sysfs_rda_audio_rate, NULL); static struct attribute *msm_dai_q6_spdif_fs_attrs[] = { &dev_attr_audio_state.attr, &dev_attr_audio_format.attr, &dev_attr_audio_rate.attr, NULL, }; static struct attribute_group msm_dai_q6_spdif_fs_attrs_group = { .attrs = msm_dai_q6_spdif_fs_attrs, }; static int msm_dai_q6_spdif_sysfs_create(struct snd_soc_dai *dai, struct msm_dai_q6_spdif_dai_data *dai_data) { int rc; rc = sysfs_create_group(&dai->dev->kobj, &msm_dai_q6_spdif_fs_attrs_group); if (rc) { pr_err("%s: failed, rc=%d\n", __func__, rc); return rc; } dai_data->kobj = &dai->dev->kobj; return 0; } static void msm_dai_q6_spdif_sysfs_remove(struct snd_soc_dai *dai, struct msm_dai_q6_spdif_dai_data *dai_data) { if (dai_data->kobj) sysfs_remove_group(dai_data->kobj, &msm_dai_q6_spdif_fs_attrs_group); dai_data->kobj = NULL; } static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) { struct msm_dai_q6_spdif_dai_data *dai_data; Loading Loading @@ -1773,40 +1814,24 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai) dai_data)); break; case AFE_PORT_ID_PRIMARY_SPDIF_TX: rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[0], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[1], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[0], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[1], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[2], dai_data)); break; case AFE_PORT_ID_SECONDARY_SPDIF_TX: rc = msm_dai_q6_spdif_sysfs_create(dai, dai_data); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[2], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_config_controls[3], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[3], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[4], dai_data)); rc = snd_ctl_add(dai->component->card->snd_card, snd_ctl_new1(&spdif_tx_status_controls[5], dai_data)); break; } if (rc < 0) Loading Loading @@ -1866,6 +1891,9 @@ static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai) clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); } msm_dai_q6_spdif_sysfs_remove(dai, dai_data); kfree(dai_data); return 0; Loading Loading @@ -2095,7 +2123,7 @@ static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params, return 0; } static u8 num_of_bits_set(u8 sd_line_mask) static u16 num_of_bits_set(u16 sd_line_mask) { u8 num_bits_set = 0; Loading Loading @@ -4644,11 +4672,68 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, dai_data->channels = params_channels(params); switch (dai_data->channels) { case 15: case 16: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_16CHS; break; default: goto error_invalid_data; }; break; case 13: case 14: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_14CHS; break; default: goto error_invalid_data; }; break; case 11: case 12: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_12CHS: case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_12CHS; break; default: goto error_invalid_data; }; break; case 9: case 10: switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_10CHS: case AFE_PORT_I2S_12CHS: case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_10CHS; break; default: goto error_invalid_data; }; break; case 8: case 7: if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_8CHS) goto error_invalid_data; dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS; else if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_8CHS_2) dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS_2; else dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_8CHS; break; case 6: case 5: Loading @@ -4658,15 +4743,34 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, break; case 4: case 3: if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_QUAD01) switch (mi2s_dai_config->pdata_mi2s_lines) { case AFE_PORT_I2S_SD0: case AFE_PORT_I2S_SD1: case AFE_PORT_I2S_SD2: case AFE_PORT_I2S_SD3: case AFE_PORT_I2S_SD4: case AFE_PORT_I2S_SD5: case AFE_PORT_I2S_SD6: case AFE_PORT_I2S_SD7: goto error_invalid_data; if (mi2s_dai_config->pdata_mi2s_lines == AFE_PORT_I2S_QUAD23) break; case AFE_PORT_I2S_QUAD01: case AFE_PORT_I2S_QUAD23: case AFE_PORT_I2S_QUAD45: case AFE_PORT_I2S_QUAD67: dai_data->port_config.i2s.channel_mode = mi2s_dai_config->pdata_mi2s_lines; else break; case AFE_PORT_I2S_8CHS_2: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_QUAD45; break; default: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_QUAD01; break; }; break; case 2: case 1: if (mi2s_dai_config->pdata_mi2s_lines < AFE_PORT_I2S_SD0) Loading @@ -4676,12 +4780,20 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, case AFE_PORT_I2S_SD1: case AFE_PORT_I2S_SD2: case AFE_PORT_I2S_SD3: case AFE_PORT_I2S_SD4: case AFE_PORT_I2S_SD5: case AFE_PORT_I2S_SD6: case AFE_PORT_I2S_SD7: dai_data->port_config.i2s.channel_mode = mi2s_dai_config->pdata_mi2s_lines; break; case AFE_PORT_I2S_QUAD01: case AFE_PORT_I2S_6CHS: case AFE_PORT_I2S_8CHS: case AFE_PORT_I2S_10CHS: case AFE_PORT_I2S_12CHS: case AFE_PORT_I2S_14CHS: case AFE_PORT_I2S_16CHS: if (dai_data->vi_feed_mono == SPKR_1) dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD0; Loading @@ -4693,6 +4805,14 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream, dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD2; break; case AFE_PORT_I2S_QUAD45: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD4; break; case AFE_PORT_I2S_QUAD67: dai_data->port_config.i2s.channel_mode = AFE_PORT_I2S_SD6; break; } if (dai_data->channels == 2) dai_data->port_config.i2s.mono_stereo = Loading Loading @@ -4866,13 +4986,15 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | SNDRV_PCM_RATE_384000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE, .rate_min = 8000, .rate_max = 192000, .rate_max = 384000, }, .capture = { .stream_name = "Primary MI2S Capture", Loading Loading @@ -5257,6 +5379,18 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_SD3; break; case MSM_MI2S_SD4: *config_ptr = AFE_PORT_I2S_SD4; break; case MSM_MI2S_SD5: *config_ptr = AFE_PORT_I2S_SD5; break; case MSM_MI2S_SD6: *config_ptr = AFE_PORT_I2S_SD6; break; case MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_SD7; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); Loading @@ -5271,6 +5405,12 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD2 | MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_QUAD23; break; case MSM_MI2S_SD4 | MSM_MI2S_SD5: *config_ptr = AFE_PORT_I2S_QUAD45; break; case MSM_MI2S_SD6 | MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_QUAD67; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); Loading @@ -5293,6 +5433,57 @@ static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3: *config_ptr = AFE_PORT_I2S_8CHS; break; case MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_8CHS_2; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 5: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4: *config_ptr = AFE_PORT_I2S_10CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 6: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5: *config_ptr = AFE_PORT_I2S_12CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 7: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6: *config_ptr = AFE_PORT_I2S_14CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); goto error_invalid_data; } break; case 8: switch (sd_lines) { case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3 | MSM_MI2S_SD4 | MSM_MI2S_SD5 | MSM_MI2S_SD6 | MSM_MI2S_SD7: *config_ptr = AFE_PORT_I2S_16CHS; break; default: pr_err("%s: invalid SD lines %d\n", __func__, sd_lines); Loading
asoc/msm-dai-q6-v2.h +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,11 @@ #define MSM_MI2S_SD1 (1 << 1) #define MSM_MI2S_SD2 (1 << 2) #define MSM_MI2S_SD3 (1 << 3) #define MSM_MI2S_SD4 (1 << 4) #define MSM_MI2S_SD5 (1 << 5) #define MSM_MI2S_SD6 (1 << 6) #define MSM_MI2S_SD7 (1 << 7) #define MSM_MI2S_CAP_RX 0 #define MSM_MI2S_CAP_TX 1 Loading
asoc/msm-pcm-q6-v2.c +60 −16 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ #include <sound/pcm_params.h> #include <dsp/msm_audio_ion.h> #include <dsp/q6audio-v2.h> #include <dsp/q6core.h> #include <dsp/q6asm-v2.h> #include "msm-pcm-q6-v2.h" #include "msm-pcm-routing-v2.h" Loading Loading @@ -384,11 +386,17 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) return -ENOMEM; } } else { if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_open_write_v5(prtd->audio_client, fmt_type, bits_per_sample); else ret = q6asm_open_write_v4(prtd->audio_client, fmt_type, bits_per_sample); if (ret < 0) { pr_err("%s: q6asm_open_write_v4 failed (%d)\n", pr_err("%s: q6asm_open_write failed (%d)\n", __func__, ret); q6asm_audio_client_free(prtd->audio_client); prtd->audio_client = NULL; Loading Loading @@ -425,6 +433,18 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) runtime->channels, !prtd->set_channel_map, prtd->channel_map, bits_per_sample); } else { if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) { ret = q6asm_media_format_block_multi_ch_pcm_v5( prtd->audio_client, runtime->rate, runtime->channels, !prtd->set_channel_map, prtd->channel_map, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } else { ret = q6asm_media_format_block_multi_ch_pcm_v4( prtd->audio_client, runtime->rate, runtime->channels, !prtd->set_channel_map, Loading @@ -432,6 +452,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream) sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); } } if (ret < 0) pr_info("%s: CMD Format block failed\n", __func__); Loading Loading @@ -489,7 +510,15 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) __func__, params_channels(params), prtd->audio_client->perf_mode); ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_open_read_v5(prtd->audio_client, FORMAT_LINEAR_PCM, bits_per_sample, false, ENC_CFG_ID_NONE); else ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM, bits_per_sample, false, ENC_CFG_ID_NONE); if (ret < 0) { pr_err("%s: q6asm_open_read failed\n", __func__); Loading Loading @@ -557,13 +586,28 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream) pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n", __func__, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size); ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client, if (q6core_get_avcs_api_version_per_service( APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >= ADSP_ASM_API_VERSION_V2) ret = q6asm_enc_cfg_blk_pcm_format_support_v5( prtd->audio_client, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); else ret = q6asm_enc_cfg_blk_pcm_format_support_v4( prtd->audio_client, prtd->samp_rate, prtd->channel_mode, bits_per_sample, sample_word_size, ASM_LITTLE_ENDIAN, DEFAULT_QF); if (ret < 0) pr_debug("%s: cmd cfg pcm was block failed", __func__); Loading Loading @@ -1508,7 +1552,7 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol, prtd = substream->runtime->private_data; if (prtd) { prtd->set_channel_map = true; for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) prtd->channel_map[i] = (char)(ucontrol->value.integer.value[i]); } Loading Loading @@ -1536,11 +1580,11 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol, prtd = substream->runtime->private_data; if (prtd && prtd->set_channel_map == true) { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = (int)prtd->channel_map[i]; } else { for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++) for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) ucontrol->value.integer.value[i] = 0; } Loading @@ -1558,7 +1602,7 @@ static int msm_pcm_add_chmap_controls(struct snd_soc_pcm_runtime *rtd) pr_debug("%s, Channel map cntrl add\n", __func__); ret = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_std_chmaps, PCM_FORMAT_MAX_NUM_CHANNEL, 0, PCM_FORMAT_MAX_NUM_CHANNEL_V8, 0, &chmap_info); if (ret < 0) { pr_err("%s, channel map cntrl add failed\n", __func__); Loading