Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfef6ec1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes I2a570ec9,I563c59eb into audio-drivers.lnx.3.0

* changes:
  asoc: sm8150: Add MultiMedia17 FE with capture support
  dsp: Add support for custom encoder
parents deb6842f 3f030f19
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -1432,6 +1432,7 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
	int dir = OUT, ret = 0;
	struct audio_client *ac = prtd->audio_client;
	uint32_t stream_index;
	uint32_t enc_cfg_id = ENC_CFG_ID_NONE;

	switch (prtd->codec_param.codec.format) {
	case SNDRV_PCM_FORMAT_S24_LE:
@@ -1450,6 +1451,9 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
	default:
		bits_per_sample = 16;
		sample_word_size = 16;
		if (prtd->codec == FORMAT_BESPOKE)
			enc_cfg_id =
			prtd->codec_param.codec.options.generic.reserved[0];
		break;
	}

@@ -1457,11 +1461,11 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
			__func__, ac->stream_id, bits_per_sample);

	if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) {
		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
			bits_per_sample, true);
		ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec,
			bits_per_sample, true, enc_cfg_id);
	} else {
		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
			bits_per_sample, false);
		ret = q6asm_open_read_v4(prtd->audio_client, prtd->codec,
			bits_per_sample, false, enc_cfg_id);
	}
	if (ret < 0) {
		pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret);
@@ -1521,10 +1525,20 @@ static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream)
	pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n",
			__func__, prtd->sample_rate, prtd->num_channels,
					 bits_per_sample, sample_word_size);
	if (prtd->codec == FORMAT_BESPOKE) {
		/*
		 * For BESPOKE codec, encoder specific config params are
		 * included as part of generic.
		 */
		ret = q6asm_enc_cfg_blk_custom(prtd->audio_client, prtd->sample_rate,
			prtd->num_channels, prtd->codec,
			(void *)&prtd->codec_param.codec.options.generic);
	} else {
		ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
					prtd->sample_rate, prtd->num_channels,
					bits_per_sample, sample_word_size,
					ASM_LITTLE_ENDIAN, DEFAULT_QF);
	}

	return ret;
}
@@ -2043,6 +2057,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
		break;
	}

	case SND_AUDIOCODEC_BESPOKE: {
		pr_debug("%s: SND_AUDIOCODEC_BESPOKE\n", __func__);
		prtd->codec = FORMAT_BESPOKE;
		break;
	}

	default:
		pr_err("codec not supported, id =%d\n", params->codec.id);
		return -EINVAL;
+1 −1
Original line number Diff line number Diff line
@@ -490,7 +490,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
				prtd->audio_client->perf_mode);

		ret = q6asm_open_read_v4(prtd->audio_client, FORMAT_LINEAR_PCM,
				bits_per_sample, false);
				bits_per_sample, false, ENC_CFG_ID_NONE);
		if (ret < 0) {
			pr_err("%s: q6asm_open_read failed\n", __func__);
			q6asm_audio_client_free(prtd->audio_client);
+15 −0
Original line number Diff line number Diff line
@@ -5668,6 +5668,21 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
		.codec_dai_name = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	{
		.name = "Compress Capture",
		.stream_name = "Compress9",
		.cpu_dai_name = "MultiMedia17",
		.platform_name = "msm-compress-dsp",
		.dynamic = 1,
		.dpcm_capture = 1,
		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
			    SND_SOC_DPCM_TRIGGER_POST},
		.codec_dai_name = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
		.ignore_suspend = 1,
		.ignore_pmdown_time = 1,
		.id = MSM_FRONTEND_DAI_MULTIMEDIA17,
	},
};

static struct snd_soc_dai_link msm_common_be_dai_links[] = {
+104 −6
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@
#define FALSE       0x00
#define SESSION_MAX 8

#define ENC_FRAMES_PER_BUFFER 0x01

enum {
	ASM_TOPOLOGY_CAL = 0,
	ASM_CUSTOM_TOP_CAL,
@@ -2812,7 +2814,7 @@ EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids);
static int __q6asm_open_read(struct audio_client *ac,
			     uint32_t format, uint16_t bits_per_sample,
			     uint32_t pcm_format_block_ver,
			     bool ts_mode)
			     bool ts_mode, uint32_t enc_cfg_id)
{
	int rc = 0x00;
	struct asm_stream_cmd_open_read_v3 open;
@@ -2888,6 +2890,12 @@ static int __q6asm_open_read(struct audio_client *ac,
		open.mode_flags |= BUFFER_META_ENABLE;
		open.enc_cfg_id = ASM_MEDIA_FMT_AMRWB_FS;
		break;
	case FORMAT_BESPOKE:
		open.mode_flags |= BUFFER_META_ENABLE;
		open.enc_cfg_id = enc_cfg_id;
		if (ts_mode)
			open.mode_flags |= ABSOLUTE_TIMESTAMP_ENABLE;
		break;
	default:
		pr_err("%s: Invalid format 0x%x\n",
			__func__, format);
@@ -2939,7 +2947,7 @@ int q6asm_open_read(struct audio_client *ac,
{
	return __q6asm_open_read(ac, format, 16,
				PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
				false/*ts_mode*/);
				false/*ts_mode*/, ENC_CFG_ID_NONE);
}
EXPORT_SYMBOL(q6asm_open_read);

@@ -2948,7 +2956,7 @@ int q6asm_open_read_v2(struct audio_client *ac, uint32_t format,
{
	return __q6asm_open_read(ac, format, bits_per_sample,
				 PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
				 false/*ts_mode*/);
				 false/*ts_mode*/, ENC_CFG_ID_NONE);
}

/*
@@ -2963,7 +2971,7 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
{
	return __q6asm_open_read(ac, format, bits_per_sample,
				 PCM_MEDIA_FORMAT_V3/*media fmt block ver*/,
				 false/*ts_mode*/);
				 false/*ts_mode*/, ENC_CFG_ID_NONE);
}
EXPORT_SYMBOL(q6asm_open_read_v3);

@@ -2976,11 +2984,12 @@ EXPORT_SYMBOL(q6asm_open_read_v3);
 * @ts_mode: timestamp mode
 */
int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
			uint16_t bits_per_sample, bool ts_mode)
			uint16_t bits_per_sample, bool ts_mode,
			uint32_t enc_cfg_id)
{
	return __q6asm_open_read(ac, format, bits_per_sample,
				 PCM_MEDIA_FORMAT_V4 /*media fmt block ver*/,
				 ts_mode);
				 ts_mode, enc_cfg_id);
}
EXPORT_SYMBOL(q6asm_open_read_v4);

@@ -4287,6 +4296,95 @@ int q6asm_stream_run_nowait(struct audio_client *ac, uint32_t flags,
	return __q6asm_run_nowait(ac, flags, msw_ts, lsw_ts, stream_id);
}

/**
 * q6asm_enc_cfg_blk_custom -
 *       command to set encode cfg block for custom
 *
 * @ac: Audio client handle
 * @sample_rate: Sample rate
 * @channels: number of ASM channels
 * @format: custom format flag
 * @cfg: generic encoder config
 *
 * Returns 0 on success or error on failure
 */
int q6asm_enc_cfg_blk_custom(struct audio_client *ac,
			uint32_t sample_rate, uint32_t channels,
			uint32_t format, void *cfg)
{
	struct asm_custom_enc_cfg_t_v2 enc_cfg;
	int rc = 0;
	uint32_t custom_size;
	struct snd_enc_generic *enc_generic = (struct snd_enc_generic *) cfg;

	custom_size = enc_generic->reserved[1];

	pr_debug("%s: session[%d] size[%d] res[2]=[%d] res[3]=[%d]\n",
		 __func__, ac->session, custom_size, enc_generic->reserved[2],
		 enc_generic->reserved[3]);

	pr_debug("%s: res[4]=[%d] sr[%d] ch[%d] format[%d]\n",
		 __func__, enc_generic->reserved[4], sample_rate,
		 channels, format);

	memset(&enc_cfg, 0, sizeof(struct asm_custom_enc_cfg_t_v2));
	q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
	atomic_set(&ac->cmd_state, -1);

	enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
	enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2;
	enc_cfg.encdec.param_size = sizeof(struct asm_custom_enc_cfg_t_v2) -
				sizeof(struct asm_stream_cmd_set_encdec_param);
	enc_cfg.encblk.frames_per_buf = ENC_FRAMES_PER_BUFFER;
	enc_cfg.encblk.enc_cfg_blk_size  = enc_cfg.encdec.param_size -
				sizeof(struct asm_enc_cfg_blk_param_v2);

	enc_cfg.num_channels = channels;
	enc_cfg.sample_rate = sample_rate;

	if (q6asm_map_channels(enc_cfg.channel_mapping, channels, false)) {
		pr_err("%s: map channels failed %d\n",
		       __func__, channels);
		rc = -EINVAL;
		goto fail_cmd;
	}

	if (format == FORMAT_BESPOKE && custom_size &&
		custom_size <= sizeof(enc_cfg.custom_data)) {
		memcpy(enc_cfg.custom_data, &enc_generic->reserved[2],
			   custom_size);
		enc_cfg.custom_size = custom_size;
	}

	rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
	if (rc < 0) {
		pr_err("%s: Comamnd %d failed %d\n",
		       __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM, rc);
		rc = -EINVAL;
		goto fail_cmd;
	}
	rc = wait_event_timeout(ac->cmd_wait,
			(atomic_read(&ac->cmd_state) >= 0), 5*HZ);
	if (!rc) {
		pr_err("%s: timeout. waited for FORMAT_UPDATE\n",
			__func__);
		rc = -ETIMEDOUT;
		goto fail_cmd;
	}
	if (atomic_read(&ac->cmd_state) > 0) {
		pr_err("%s: DSP returned error[%s]\n",
					__func__, adsp_err_get_err_str(
					atomic_read(&ac->cmd_state)));
		rc = adsp_err_get_lnx_err_code(
				atomic_read(&ac->cmd_state));
		goto fail_cmd;
	}
	return 0;
fail_cmd:
	return rc;
}
EXPORT_SYMBOL(q6asm_enc_cfg_blk_custom);

/**
 * q6asm_enc_cfg_blk_aac -
 *       command to set encode cfg block for aac
+16 −0
Original line number Diff line number Diff line
@@ -4743,6 +4743,22 @@ struct asm_enc_cfg_blk_param_v2 {

} __packed;

struct asm_custom_enc_cfg_t_v2 {
	struct apr_hdr hdr;
	struct asm_stream_cmd_set_encdec_param encdec;
	struct asm_enc_cfg_blk_param_v2 encblk;
	uint32_t sample_rate;

	uint16_t num_channels;
	uint16_t reserved;
	/* num_ch == 1, then PCM_CHANNEL_C,
	 * num_ch == 2, then {PCM_CHANNEL_L, PCM_CHANNEL_R}
	 */
	uint8_t  channel_mapping[8];
	uint32_t  custom_size;
	uint8_t  custom_data[15];
} __packed;

/* @brief Dolby Digital Plus end point configuration structure
 */
struct asm_dec_ddp_endp_param_v2 {
Loading