mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
ASoC: msm: flush if prior and current backends rate not matching
It is found that during device switch from one backend with one sample rate to another backend with another sample rate, the command to QDSP6 ADM which maps audio stream session to a particular backend would not get carried out until pending data of audio stream session from previous backend is either read out or flushed. This scenario occurs when application stops providing more buffers to retrieve captured data. Remedy is to flush upon detection of rate mismatching Change-Id: I2c01c036d9bb71f938a6795337f08948bd986553 CRs-fixed: 422205 Signed-off-by: Patrick Lai <plai@codeaurora.org> Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
This commit is contained in:
parent
799b9c14c2
commit
7d142e34bd
5 changed files with 187 additions and 60 deletions
|
@ -71,6 +71,8 @@
|
|||
/* Enable Sample_Rate/Channel_Mode notification event from Decoder */
|
||||
#define SR_CM_NOTIFY_ENABLE 0x0004
|
||||
|
||||
#define TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */
|
||||
#define TUN_READ_IO_MODE 0x0004 /* tunnel read write mode */
|
||||
#define ASYNC_IO_MODE 0x0002
|
||||
#define SYNC_IO_MODE 0x0001
|
||||
#define NO_TIMESTAMP 0xFF00
|
||||
|
|
|
@ -100,6 +100,25 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
|
|||
.mask = 0,
|
||||
};
|
||||
|
||||
static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
|
||||
void *priv_data)
|
||||
{
|
||||
struct msm_audio *prtd = priv_data;
|
||||
|
||||
BUG_ON(!prtd);
|
||||
|
||||
pr_debug("%s: event %x\n", __func__, event);
|
||||
|
||||
switch (event) {
|
||||
case MSM_PCM_RT_EVT_BUF_RECFG:
|
||||
q6asm_cmd(prtd->audio_client, CMD_PAUSE);
|
||||
q6asm_cmd(prtd->audio_client, CMD_FLUSH);
|
||||
q6asm_run(prtd->audio_client, 0, 0, 0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void event_handler(uint32_t opcode,
|
||||
uint32_t token, uint32_t *payload, void *priv)
|
||||
{
|
||||
|
@ -146,6 +165,9 @@ static void event_handler(uint32_t opcode,
|
|||
pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
|
||||
in_frame_info[token][0] = payload[2];
|
||||
in_frame_info[token][1] = payload[3];
|
||||
|
||||
/* assume data size = 0 during flushing */
|
||||
if (in_frame_info[token][0]) {
|
||||
prtd->pcm_irq_pos += in_frame_info[token][0];
|
||||
pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
|
||||
if (atomic_read(&prtd->start))
|
||||
|
@ -153,11 +175,23 @@ static void event_handler(uint32_t opcode,
|
|||
if (atomic_read(&prtd->in_count) <= prtd->periods)
|
||||
atomic_inc(&prtd->in_count);
|
||||
wake_up(&the_locks.read_wait);
|
||||
if (prtd->mmap_flag
|
||||
&& q6asm_is_cpu_buf_avail_nolock(OUT,
|
||||
if (prtd->mmap_flag &&
|
||||
q6asm_is_cpu_buf_avail_nolock(OUT,
|
||||
prtd->audio_client,
|
||||
&size, &idx))
|
||||
q6asm_read_nolock(prtd->audio_client);
|
||||
} else {
|
||||
pr_debug("%s: reclaim flushed buf in_count %x\n",
|
||||
__func__, atomic_read(&prtd->in_count));
|
||||
atomic_inc(&prtd->in_count);
|
||||
if (atomic_read(&prtd->in_count) == prtd->periods) {
|
||||
pr_info("%s: reclaimed all bufs\n", __func__);
|
||||
if (atomic_read(&prtd->start))
|
||||
snd_pcm_period_elapsed(substream);
|
||||
wake_up(&the_locks.read_wait);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case APR_BASIC_RSP_RESULT: {
|
||||
|
@ -642,6 +676,7 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
struct audio_buffer *buf;
|
||||
int dir, ret;
|
||||
int format = FORMAT_LINEAR_PCM;
|
||||
struct msm_pcm_routing_evt event;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dir = IN;
|
||||
|
@ -665,9 +700,12 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
pr_debug("%s: session ID %d\n", __func__,
|
||||
prtd->audio_client->session);
|
||||
prtd->session_id = prtd->audio_client->session;
|
||||
msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
|
||||
event.event_func = msm_pcm_route_event_handler;
|
||||
event.priv_data = (void *) prtd;
|
||||
msm_pcm_routing_reg_phy_stream_v2(soc_prtd->dai_link->be_id,
|
||||
prtd->audio_client->perf_mode,
|
||||
prtd->session_id, substream->stream);
|
||||
prtd->session_id,
|
||||
substream->stream, event);
|
||||
}
|
||||
|
||||
if (dir == OUT) {
|
||||
|
|
|
@ -41,6 +41,12 @@ struct msm_pcm_routing_bdai_data {
|
|||
bool perf_mode;
|
||||
};
|
||||
|
||||
struct msm_pcm_routing_fdai_data {
|
||||
u16 be_srate; /* track prior backend sample rate for flushing purpose */
|
||||
int strm_id; /* ASM stream ID */
|
||||
struct msm_pcm_routing_evt event_info;
|
||||
};
|
||||
|
||||
#define INVALID_SESSION -1
|
||||
#define SESSION_TYPE_RX 0
|
||||
#define SESSION_TYPE_TX 1
|
||||
|
@ -194,24 +200,32 @@ static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
|
|||
|
||||
|
||||
/* Track ASM playback & capture sessions of DAI */
|
||||
static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
|
||||
static struct msm_pcm_routing_fdai_data
|
||||
fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
|
||||
/* MULTIMEDIA1 */
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
/* MULTIMEDIA2 */
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
/* MULTIMEDIA3 */
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
/* MULTIMEDIA4 */
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
/* MULTIMEDIA5 */
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
/* MULTIMEDIA6 */
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
/* MULTIMEDIA7*/
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
/* MULTIMEDIA8 */
|
||||
{INVALID_SESSION, INVALID_SESSION},
|
||||
|
||||
{{0, INVALID_SESSION, {NULL, NULL} },
|
||||
{0, INVALID_SESSION, {NULL, NULL} } },
|
||||
};
|
||||
|
||||
static uint8_t is_be_dai_extproc(int be_dai)
|
||||
|
@ -272,7 +286,7 @@ void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
|
|||
|
||||
mutex_lock(&routing_lock);
|
||||
|
||||
fe_dai_map[fedai_id][session_type] = dspst_id;
|
||||
fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
|
||||
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
|
||||
if (!is_be_dai_extproc(i) &&
|
||||
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
|
||||
|
@ -318,7 +332,7 @@ void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode, int dspst_id,
|
|||
mutex_lock(&routing_lock);
|
||||
|
||||
payload.num_copps = 0; /* only RX needs to use payload */
|
||||
fe_dai_map[fedai_id][session_type] = dspst_id;
|
||||
fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
|
||||
/* re-enable EQ if active */
|
||||
if (eq_data[fedai_id].enable)
|
||||
msm_send_eq_values(fedai_id);
|
||||
|
@ -368,6 +382,19 @@ void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode, int dspst_id,
|
|||
|
||||
mutex_unlock(&routing_lock);
|
||||
}
|
||||
void msm_pcm_routing_reg_phy_stream_v2(int fedai_id, bool perf_mode,
|
||||
int dspst_id, int stream_type,
|
||||
struct msm_pcm_routing_evt event_info)
|
||||
{
|
||||
msm_pcm_routing_reg_phy_stream(fedai_id, perf_mode, dspst_id,
|
||||
stream_type);
|
||||
|
||||
if (stream_type == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
fe_dai_map[fedai_id][SESSION_TYPE_RX].event_info = event_info;
|
||||
else
|
||||
fe_dai_map[fedai_id][SESSION_TYPE_TX].event_info = event_info;
|
||||
|
||||
}
|
||||
|
||||
void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
|
||||
{
|
||||
|
@ -397,8 +424,8 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
|
|||
adm_close(msm_bedais[i].port_id);
|
||||
}
|
||||
|
||||
fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
|
||||
|
||||
fe_dai_map[fedai_id][session_type].strm_id = INVALID_SESSION;
|
||||
fe_dai_map[fedai_id][session_type].be_srate = 0;
|
||||
mutex_unlock(&routing_lock);
|
||||
}
|
||||
|
||||
|
@ -423,6 +450,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
|
|||
{
|
||||
int session_type, path_type;
|
||||
u32 channels;
|
||||
struct msm_pcm_routing_fdai_data *fdai;
|
||||
|
||||
pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
|
||||
|
||||
|
@ -449,11 +477,24 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
|
|||
voc_start_playback(set);
|
||||
|
||||
set_bit(val, &msm_bedais[reg].fe_sessions);
|
||||
if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
|
||||
fdai = &fe_dai_map[val][session_type];
|
||||
if (msm_bedais[reg].active && fdai->strm_id !=
|
||||
INVALID_SESSION) {
|
||||
|
||||
channels = msm_bedais[reg].channel;
|
||||
|
||||
if (session_type == SESSION_TYPE_TX && fdai->be_srate &&
|
||||
(fdai->be_srate != msm_bedais[reg].sample_rate)) {
|
||||
pr_debug("%s: flush strm %d due diff BE rates\n",
|
||||
__func__, fdai->strm_id);
|
||||
|
||||
if (fdai->event_info.event_func)
|
||||
fdai->event_info.event_func(
|
||||
MSM_PCM_RT_EVT_BUF_RECFG,
|
||||
fdai->event_info.priv_data);
|
||||
fdai->be_srate = 0; /* might not need it */
|
||||
}
|
||||
|
||||
if ((session_type == SESSION_TYPE_RX) &&
|
||||
((channels == 1) || (channels == 2))
|
||||
&& msm_bedais[reg].perf_mode) {
|
||||
|
@ -481,7 +522,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
|
|||
|
||||
|
||||
msm_pcm_routing_build_matrix(val,
|
||||
fe_dai_map[val][session_type], path_type);
|
||||
fdai->strm_id, path_type);
|
||||
srs_port_id = msm_bedais[reg].port_id;
|
||||
srs_send_params(srs_port_id, 1, 0);
|
||||
}
|
||||
|
@ -490,11 +531,13 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
|
|||
(msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
|
||||
voc_start_playback(set);
|
||||
clear_bit(val, &msm_bedais[reg].fe_sessions);
|
||||
if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
|
||||
fdai = &fe_dai_map[val][session_type];
|
||||
if (msm_bedais[reg].active && fdai->strm_id !=
|
||||
INVALID_SESSION) {
|
||||
fdai->be_srate = msm_bedais[reg].sample_rate;
|
||||
adm_close(msm_bedais[reg].port_id);
|
||||
msm_pcm_routing_build_matrix(val,
|
||||
fe_dai_map[val][session_type], path_type);
|
||||
fdai->strm_id, path_type);
|
||||
}
|
||||
}
|
||||
if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
|
||||
|
@ -970,12 +1013,12 @@ static int msm_routing_set_srs_trumedia_control_HDMI(
|
|||
static void msm_send_eq_values(int eq_idx)
|
||||
{
|
||||
int result;
|
||||
struct audio_client *ac =
|
||||
q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
|
||||
struct audio_client *ac = q6asm_get_audio_client(
|
||||
fe_dai_map[eq_idx][SESSION_TYPE_RX].strm_id);
|
||||
|
||||
if (ac == NULL) {
|
||||
pr_err("%s: Could not get audio client for session: %d\n",
|
||||
__func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
|
||||
__func__, fe_dai_map[eq_idx][SESSION_TYPE_RX].strm_id);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -2640,7 +2683,9 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
|
|||
mutex_lock(&routing_lock);
|
||||
|
||||
for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
|
||||
if (fe_dai_map[i][session_type] != INVALID_SESSION) {
|
||||
if (fe_dai_map[i][session_type].strm_id != INVALID_SESSION) {
|
||||
fe_dai_map[i][session_type].be_srate =
|
||||
bedai->sample_rate;
|
||||
adm_close(bedai->port_id);
|
||||
srs_port_id = -1;
|
||||
}
|
||||
|
@ -2663,6 +2708,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
|
|||
struct msm_pcm_routing_bdai_data *bedai;
|
||||
u32 channels;
|
||||
bool playback, capture;
|
||||
struct msm_pcm_routing_fdai_data *fdai;
|
||||
|
||||
if (be_id >= MSM_BACKEND_DAI_MAX) {
|
||||
pr_err("%s: unexpected be_id %d\n", __func__, be_id);
|
||||
|
@ -2694,7 +2740,21 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
|
|||
capture = substream->stream == SNDRV_PCM_STREAM_CAPTURE;
|
||||
|
||||
for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
|
||||
if (fe_dai_map[i][session_type] != INVALID_SESSION) {
|
||||
fdai = &fe_dai_map[i][session_type];
|
||||
if (fdai->strm_id != INVALID_SESSION) {
|
||||
if (session_type == SESSION_TYPE_TX && fdai->be_srate &&
|
||||
(fdai->be_srate != bedai->sample_rate)) {
|
||||
pr_debug("%s: flush strm %d due diff BE rates\n",
|
||||
__func__,
|
||||
fdai->strm_id);
|
||||
|
||||
if (fdai->event_info.event_func)
|
||||
fdai->event_info.event_func(
|
||||
MSM_PCM_RT_EVT_BUF_RECFG,
|
||||
fdai->event_info.priv_data);
|
||||
fdai->be_srate = 0; /* might not need it */
|
||||
}
|
||||
|
||||
channels = bedai->channel;
|
||||
if ((playback || capture)
|
||||
&& ((channels == 2) || (channels == 1)) &&
|
||||
|
@ -2721,7 +2781,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
|
|||
DEFAULT_COPP_TOPOLOGY);
|
||||
|
||||
msm_pcm_routing_build_matrix(i,
|
||||
fe_dai_map[i][session_type], path_type);
|
||||
fdai->strm_id, path_type);
|
||||
srs_port_id = bedai->port_id;
|
||||
srs_send_params(srs_port_id, 1, 0);
|
||||
}
|
||||
|
|
|
@ -107,6 +107,10 @@ enum {
|
|||
MSM_BACKEND_DAI_MAX,
|
||||
};
|
||||
|
||||
enum msm_pcm_routing_event {
|
||||
MSM_PCM_RT_EVT_BUF_RECFG,
|
||||
MSM_PCM_RT_EVT_MAX,
|
||||
};
|
||||
/* dai_id: front-end ID,
|
||||
* dspst_id: DSP audio stream ID
|
||||
* stream_type: playback or capture
|
||||
|
@ -116,6 +120,15 @@ void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode,
|
|||
void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
|
||||
int stream_type, int enable);
|
||||
|
||||
struct msm_pcm_routing_evt {
|
||||
void (*event_func)(enum msm_pcm_routing_event, void *);
|
||||
void *priv_data;
|
||||
};
|
||||
|
||||
void msm_pcm_routing_reg_phy_stream_v2(int fedai_id, bool perf_mode,
|
||||
int dspst_id, int stream_type,
|
||||
struct msm_pcm_routing_evt event_info);
|
||||
|
||||
void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type);
|
||||
|
||||
int lpa_set_volume(unsigned volume);
|
||||
|
|
|
@ -220,7 +220,7 @@ int q6asm_audio_client_buf_free(unsigned int dir,
|
|||
int rc = 0;
|
||||
pr_debug("%s: Session id %d\n", __func__, ac->session);
|
||||
mutex_lock(&ac->cmd_lock);
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
port = &ac->port[dir];
|
||||
if (!port->buf) {
|
||||
mutex_unlock(&ac->cmd_lock);
|
||||
|
@ -351,7 +351,7 @@ void q6asm_audio_client_free(struct audio_client *ac)
|
|||
if (!ac || !ac->session)
|
||||
return;
|
||||
pr_debug("%s: Session id %d\n", __func__, ac->session);
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
|
||||
port = &ac->port[loopcnt];
|
||||
if (!port->buf)
|
||||
|
@ -386,14 +386,20 @@ int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode)
|
|||
pr_err("%s APR handle NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((mode == ASYNC_IO_MODE) || (mode == SYNC_IO_MODE)) {
|
||||
ac->io_mode = mode;
|
||||
pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
|
||||
return 0;
|
||||
|
||||
if (mode == ASYNC_IO_MODE) {
|
||||
ac->io_mode &= ~SYNC_IO_MODE;
|
||||
ac->io_mode |= ASYNC_IO_MODE;
|
||||
} else if (mode == SYNC_IO_MODE) {
|
||||
ac->io_mode &= ~ASYNC_IO_MODE;
|
||||
ac->io_mode |= SYNC_IO_MODE;
|
||||
} else {
|
||||
pr_err("%s:Not an valid IO Mode:%d\n", __func__, ac->io_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
|
||||
|
@ -497,7 +503,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir,
|
|||
if (ac->session <= 0 || ac->session > 8)
|
||||
goto fail;
|
||||
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
if (ac->port[dir].buf) {
|
||||
pr_debug("%s: buffer already allocated\n", __func__);
|
||||
return 0;
|
||||
|
@ -922,7 +928,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
pr_debug("%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
|
||||
__func__, payload[0], payload[1],
|
||||
data->token);
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
if (port->buf == NULL) {
|
||||
pr_err("%s: Unexpected Write Done\n",
|
||||
__func__);
|
||||
|
@ -1004,7 +1010,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
if (in_enable_flag)
|
||||
in_cont_index++;
|
||||
#endif
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
if (port->buf == NULL) {
|
||||
pr_err("%s: Unexpected Write Done\n", __func__);
|
||||
return -EINVAL;
|
||||
|
@ -1073,7 +1079,7 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size,
|
|||
if (!ac || ((dir != IN) && (dir != OUT)))
|
||||
return NULL;
|
||||
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
port = &ac->port[dir];
|
||||
|
||||
mutex_lock(&port->lock);
|
||||
|
@ -1167,7 +1173,7 @@ int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac)
|
|||
if (!ac || (dir != OUT))
|
||||
return ret;
|
||||
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
port = &ac->port[dir];
|
||||
|
||||
mutex_lock(&port->lock);
|
||||
|
@ -1298,6 +1304,9 @@ int q6asm_open_read(struct audio_client *ac,
|
|||
rc);
|
||||
goto fail_cmd;
|
||||
}
|
||||
|
||||
ac->io_mode |= TUN_READ_IO_MODE;
|
||||
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return -EINVAL;
|
||||
|
@ -1574,6 +1583,9 @@ int q6asm_open_write(struct audio_client *ac, uint32_t format)
|
|||
pr_err("%s: format = %x not supported\n", __func__, format);
|
||||
goto fail_cmd;
|
||||
}
|
||||
|
||||
ac->io_mode |= TUN_WRITE_IO_MODE;
|
||||
|
||||
return 0;
|
||||
fail_cmd:
|
||||
return -EINVAL;
|
||||
|
@ -3322,7 +3334,7 @@ int q6asm_read(struct audio_client *ac)
|
|||
pr_err("APR handle NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
port = &ac->port[OUT];
|
||||
|
||||
q6asm_add_hdr(ac, &read.hdr, sizeof(read), FALSE);
|
||||
|
@ -3374,7 +3386,7 @@ int q6asm_read_nolock(struct audio_client *ac)
|
|||
pr_err("APR handle NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
port = &ac->port[OUT];
|
||||
|
||||
q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
|
||||
|
@ -3398,7 +3410,7 @@ int q6asm_read_nolock(struct audio_client *ac)
|
|||
read.hdr.token = port->dsp_buf;
|
||||
|
||||
port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
|
||||
pr_debug("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
|
||||
pr_info("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
|
||||
read.buf_add,
|
||||
read.hdr.token,
|
||||
read.uid);
|
||||
|
@ -3559,7 +3571,7 @@ int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
|
|||
return -EINVAL;
|
||||
}
|
||||
pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
port = &ac->port[IN];
|
||||
|
||||
q6asm_add_hdr(ac, &write.hdr, sizeof(write),
|
||||
|
@ -3641,7 +3653,7 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
|
|||
return -EINVAL;
|
||||
}
|
||||
pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
port = &ac->port[IN];
|
||||
|
||||
q6asm_add_hdr_async(ac, &write.hdr, sizeof(write),
|
||||
|
@ -3845,9 +3857,11 @@ static void q6asm_reset_buf_state(struct audio_client *ac)
|
|||
{
|
||||
int cnt = 0;
|
||||
int loopcnt = 0;
|
||||
int used;
|
||||
struct audio_port_data *port = NULL;
|
||||
|
||||
if (ac->io_mode == SYNC_IO_MODE) {
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
used = (ac->io_mode & TUN_WRITE_IO_MODE ? 1 : 0);
|
||||
mutex_lock(&ac->cmd_lock);
|
||||
for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
|
||||
port = &ac->port[loopcnt];
|
||||
|
@ -3857,7 +3871,7 @@ static void q6asm_reset_buf_state(struct audio_client *ac)
|
|||
while (cnt >= 0) {
|
||||
if (!port->buf)
|
||||
continue;
|
||||
port->buf[cnt].used = 1;
|
||||
port->buf[cnt].used = used;
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue