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

Commit 83c60330 authored by Zhou Song's avatar Zhou Song
Browse files

asoc: add new fe for hearing aid



Add a new fe dedicated for hearing aid and the support
of reading data from a new proxy port.

Change-Id: Id2e8ade6bfe5412ca6520d3cff70d6eebad7d7cc
Signed-off-by: default avatarZhou Song <zhous@codeaurora.org>
parent a2efe09c
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -2620,6 +2620,7 @@ static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream,
	case RT_PROXY_DAI_001_RX:
	case RT_PROXY_DAI_002_TX:
	case RT_PROXY_DAI_002_RX:
	case RT_PROXY_DAI_003_TX:
	case RT_PROXY_PORT_002_TX:
	case RT_PROXY_PORT_002_RX:
		rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai);
@@ -4087,6 +4088,23 @@ static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai[] = {
	},
};

static struct snd_soc_dai_driver msm_dai_q6_afe_cap_dai = {
	.capture = {
		.stream_name = "AFE-PROXY TX1",
		.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
		SNDRV_PCM_RATE_16000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE,
		.channels_min = 1,
		.channels_max = 8,
		.rate_min =     8000,
		.rate_max =     48000,
	},
	.ops = &msm_dai_q6_ops,
	.id = RT_PROXY_DAI_003_TX,
	.probe = msm_dai_q6_dai_probe,
	.remove = msm_dai_q6_dai_remove,
};

static struct snd_soc_dai_driver msm_dai_q6_bt_sco_rx_dai = {
	.playback = {
		.stream_name = "Internal BT-SCO Playback",
@@ -7279,6 +7297,10 @@ static int msm_dai_q6_dev_probe(struct platform_device *pdev)
			pr_err("%s: Device not found stream name %s\n",
			__func__, stream_name);
		break;
        case RT_PROXY_DAI_003_TX:
		rc = snd_soc_register_component(&pdev->dev,
			&msm_dai_q6_component, &msm_dai_q6_afe_cap_dai, 1);
		break;
	case VOICE_PLAYBACK_TX:
		strlcpy(stream_name, "Voice Farend Playback", 80);
		goto register_voice_playback;
+14 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 */


@@ -124,7 +124,9 @@ static enum hrtimer_restart afe_hrtimer_rec_callback(struct hrtimer *hrt)
		container_of(hrt, struct pcm_afe_info, hrt);
	struct snd_pcm_substream *substream = prtd->substream;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	u32 mem_map_handle = 0;
	int port_id = rtd->cpu_dai->id;
	int ret;

	mem_map_handle = afe_req_mmap_handle(prtd->audio_client);
@@ -138,7 +140,7 @@ static enum hrtimer_restart afe_hrtimer_rec_callback(struct hrtimer *hrt)
		ret = afe_rt_proxy_port_read(
		(prtd->dma_addr + (prtd->dsp_cnt
		* snd_pcm_lib_period_bytes(prtd->substream))), mem_map_handle,
		snd_pcm_lib_period_bytes(prtd->substream));
		snd_pcm_lib_period_bytes(prtd->substream), port_id);
		if (ret < 0) {
			pr_err("%s: AFE port read fails: %d\n", __func__, ret);
			prtd->start = 0;
@@ -256,15 +258,19 @@ static void pcm_afe_process_rx_pkt(uint32_t opcode,
	unsigned long dsp_flags;
	struct snd_pcm_substream *substream = NULL;
	struct snd_pcm_runtime *runtime = NULL;
	struct snd_soc_pcm_runtime *rtd = NULL;
	uint16_t event;
	uint64_t period_bytes;
	uint64_t bytes_one_sec;
	uint32_t mem_map_handle = 0;
	int port_id = 0;

	if (prtd == NULL)
		return;
	substream =  prtd->substream;
	runtime = substream->runtime;
	rtd = substream->private_data;
	port_id = rtd->cpu_dai->id;
	pr_debug("%s\n", __func__);
	spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
	switch (opcode) {
@@ -305,7 +311,8 @@ static void pcm_afe_process_rx_pkt(uint32_t opcode,
						prtd->substream))),
					mem_map_handle,
					snd_pcm_lib_period_bytes(
						prtd->substream));
						prtd->substream),
					port_id);
				prtd->dsp_cnt++;
			}
			break;
@@ -543,6 +550,8 @@ static int msm_afe_capture_copy(struct snd_pcm_substream *substream,
	int ret = 0;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct pcm_afe_info *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	int port_id = rtd->cpu_dai->id;
	char *hwbuf = runtime->dma_area + hwoff;
	u32 mem_map_handle = 0;

@@ -562,7 +571,8 @@ static int msm_afe_capture_copy(struct snd_pcm_substream *substream,
				(prtd->dsp_cnt *
				snd_pcm_lib_period_bytes(prtd->substream))),
				mem_map_handle,
				snd_pcm_lib_period_bytes(prtd->substream));
				snd_pcm_lib_period_bytes(prtd->substream),
				port_id);

		if (ret) {
			pr_err("%s: AFE proxy port read failed %d\n",
+39 −9
Original line number Diff line number Diff line
@@ -181,6 +181,8 @@ static int pcm_afe_instance[2];
static int proxy_afe_instance[2];
bool afe_close_done[2] = {true, true};

static bool proxy_afe_started = false;

#define SIZEOF_CFG_CMD(y) \
		(sizeof(struct apr_hdr) + sizeof(u16) + (sizeof(struct y)))

@@ -855,7 +857,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
			}
			break;
		}
		case RT_PROXY_PORT_001_RX: {
		case RT_PROXY_PORT_001_RX:
		case RT_PROXY_PORT_002_RX:
		{
			if (this_afe.rx_cb) {
				this_afe.rx_cb(data->opcode, data->token,
					data->payload,
@@ -4359,7 +4363,23 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
		ret = -EINVAL;
		return ret;
	}

	if (port_id == RT_PROXY_PORT_002_RX) {
		if (proxy_afe_started) {
			pr_debug("%s: afe port already started, port id 0x%x\n",
				__func__, RT_PROXY_PORT_002_RX);
			return 0;
		} else {
			proxy_afe_started = true;
		}
	}
	if (port_id == RT_PROXY_DAI_003_TX) {
		port_id = VIRTUAL_ID_TO_PORTID(port_id);
		if (proxy_afe_started) {
			pr_debug("%s: reconfigure afe port again\n", __func__);
			afe_close(port_id);
		}
		proxy_afe_started = true;
	}
	if ((port_id == RT_PROXY_DAI_001_RX) ||
		(port_id == RT_PROXY_DAI_002_TX)) {
		pr_debug("%s: before incrementing pcm_afe_instance %d port_id 0x%x\n",
@@ -6290,7 +6310,8 @@ int afe_register_get_events(u16 port_id,
		rtac_set_afe_handle(this_afe.apr);
	}
	if ((port_id == RT_PROXY_DAI_002_RX) ||
		(port_id == RT_PROXY_DAI_001_TX)) {
		(port_id == RT_PROXY_DAI_001_TX) ||
		(port_id == RT_PROXY_DAI_003_TX)) {
		port_id = VIRTUAL_ID_TO_PORTID(port_id);
	} else {
		pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
@@ -6300,7 +6321,8 @@ int afe_register_get_events(u16 port_id,
	if (port_id == RT_PROXY_PORT_001_TX) {
		this_afe.tx_cb = cb;
		this_afe.tx_private_data = private_data;
	} else if (port_id == RT_PROXY_PORT_001_RX) {
	} else if (port_id == RT_PROXY_PORT_001_RX ||
			port_id == RT_PROXY_PORT_002_RX) {
		this_afe.rx_cb = cb;
		this_afe.rx_private_data = private_data;
	}
@@ -6351,7 +6373,8 @@ int afe_unregister_get_events(u16 port_id)
	}

	if ((port_id == RT_PROXY_DAI_002_RX) ||
		(port_id == RT_PROXY_DAI_001_TX)) {
		(port_id == RT_PROXY_DAI_001_TX) ||
		(port_id == RT_PROXY_DAI_003_TX)) {
		port_id = VIRTUAL_ID_TO_PORTID(port_id);
	} else {
		pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
@@ -6385,7 +6408,8 @@ int afe_unregister_get_events(u16 port_id)
	if (port_id == RT_PROXY_PORT_001_TX) {
		this_afe.tx_cb = NULL;
		this_afe.tx_private_data = NULL;
	} else if (port_id == RT_PROXY_PORT_001_RX) {
	} else if (port_id == RT_PROXY_PORT_001_RX ||
			port_id == RT_PROXY_PORT_002_RX) {
		this_afe.rx_cb = NULL;
		this_afe.rx_private_data = NULL;
	}
@@ -6463,14 +6487,16 @@ EXPORT_SYMBOL(afe_rt_proxy_port_write);
 * @buf_addr_p: Physical buffer address to fill read data
 * @mem_map_handle: memory map handle for buffer read
 * @bytes: number of bytes to read
 * @id: afe virtual port id
 *
 * Returns 0 on success or error on failure
 */
int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
		u32 mem_map_handle, int bytes)
		u32 mem_map_handle, int bytes, int id)
{
	int ret = 0;
	struct afe_port_data_cmd_rt_proxy_port_read_v2 afecmd_rd;
	int port_id = VIRTUAL_ID_TO_PORTID(id);

	if (this_afe.apr == NULL) {
		pr_err("%s: register to AFE is not done\n", __func__);
@@ -6487,7 +6513,7 @@ int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
	afecmd_rd.hdr.dest_port = 0;
	afecmd_rd.hdr.token = 0;
	afecmd_rd.hdr.opcode = AFE_PORT_DATA_CMD_RT_PROXY_PORT_READ_V2;
	afecmd_rd.port_id = RT_PROXY_PORT_001_RX;
	afecmd_rd.port_id = port_id;
	afecmd_rd.buffer_address_lsw = lower_32_bits(buf_addr_p);
	afecmd_rd.buffer_address_msw =
				msm_audio_populate_upper_32_bits(buf_addr_p);
@@ -7344,7 +7370,8 @@ int afe_convert_virtual_to_portid(u16 port_id)
		if (port_id == RT_PROXY_DAI_001_RX ||
		    port_id == RT_PROXY_DAI_001_TX ||
		    port_id == RT_PROXY_DAI_002_RX ||
		    port_id == RT_PROXY_DAI_002_TX) {
		    port_id == RT_PROXY_DAI_002_TX ||
		    port_id == RT_PROXY_DAI_003_TX) {
			ret = VIRTUAL_ID_TO_PORTID(port_id);
		} else {
			pr_err("%s: wrong port 0x%x\n",
@@ -7444,6 +7471,9 @@ int afe_close(int port_id)
		afe_close_done[port_id & 0x1] = true;
	}

	if (port_id == RT_PROXY_PORT_002_RX && proxy_afe_started)
		proxy_afe_started = false;

	port_id = q6audio_convert_virtual_to_portid(port_id);
	index = q6audio_get_port_index(port_id);
	if (index < 0 || index >= AFE_MAX_PORTS) {
+2 −1
Original line number Diff line number Diff line
@@ -791,7 +791,8 @@ int q6audio_convert_virtual_to_portid(u16 port_id)
		if (port_id == RT_PROXY_DAI_001_RX ||
			port_id == RT_PROXY_DAI_001_TX ||
			port_id == RT_PROXY_DAI_002_RX ||
			port_id == RT_PROXY_DAI_002_TX)
			port_id == RT_PROXY_DAI_002_TX ||
			port_id == RT_PROXY_DAI_003_TX)
			ret = VIRTUAL_ID_TO_PORTID(port_id);
		else
			ret = -EINVAL;
+2 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#define RT_PROXY_DAI_001_TX	0xF0
#define RT_PROXY_DAI_002_RX	0xF1
#define RT_PROXY_DAI_002_TX	0xE1
#define RT_PROXY_DAI_003_TX	0xF2
#define VIRTUAL_ID_TO_PORTID(val) ((val & 0xF) | 0x2000)

#define AFE_CLK_VERSION_V1    1
@@ -387,7 +388,7 @@ int afe_unregister_get_events(u16 port_id);
int afe_rt_proxy_port_write(phys_addr_t buf_addr_p,
			u32 mem_map_handle, int bytes);
int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
			u32 mem_map_handle, int bytes);
			u32 mem_map_handle, int bytes, int id);
void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode);
void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config,
		     u32 port_id);