Skip to content
This repository has been archived by the owner on Dec 28, 2020. It is now read-only.

Commit

Permalink
techpack: audio: Merge tag 'LA.UM.7.3.r1-07400-sdm845.0' into neutrin…
Browse files Browse the repository at this point in the history
…o-msm-fajita-4.9

"LA.UM.7.3.r1-07400-sdm845.0"

* tag 'LA.UM.7.3.r1-07400-sdm845.0':
  asoc: check payload length against structure size
  dsp: asm: Add check for num_channels before calling q6asm_map_channels
  ipc: apr: check for packet size to header size comparison
  asoc: pcm: add qtime mixer control
  asoc: Add FE dai's for Haptics Audio
  dsp: asm: validate ADSP data size before access
  asoc: Add support for Haptics Audio
  dsp: validate token before usage as array index
  dsp: codecs: fix range check for audio buffer copying
  dsp: asm: Remove redundant payload size check
  dsp: asm: validate payload size before access

Signed-off-by: Adam W. Willis <return.of.octobot@gmail.com>
  • Loading branch information
0ctobot committed May 4, 2019
2 parents 2c1b2ab + b483346 commit 656fac7
Show file tree
Hide file tree
Showing 12 changed files with 794 additions and 173 deletions.
40 changes: 39 additions & 1 deletion techpack/audio/asoc/msm-dai-fe.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -2569,6 +2569,44 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.name = "MultiMedia20",
.probe = fe_dai_probe,
},
{
.playback = {
.stream_name = "MultiMedia21 Playback",
.aif_name = "MM_DL21",
.rates = (SNDRV_PCM_RATE_8000_384000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia21",
.probe = fe_dai_probe,
},
{
.playback = {
.stream_name = "MultiMedia22 Playback",
.aif_name = "MM_DL22",
.rates = (SNDRV_PCM_RATE_8000_384000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE |
SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 384000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia22",
.probe = fe_dai_probe,
},
{
.capture = {
.stream_name = "MultiMedia28 Capture",
Expand Down
31 changes: 29 additions & 2 deletions techpack/audio/asoc/msm-dai-q6-v2.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -6853,6 +6853,31 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
return rc;
}

static unsigned int tdm_param_set_slot_mask(u16 *slot_offset, int slot_width,
int slots_per_frame)
{
unsigned int i = 0;
unsigned int slot_index = 0;
unsigned long slot_mask = 0;
unsigned int slot_width_bytes = slot_width / 8;

for (i = 0; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) {
if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) {
slot_index = slot_offset[i] / slot_width_bytes;
if (slot_index < slots_per_frame)
set_bit(slot_index, &slot_mask);
else {
pr_err("%s: invalid slot map setting\n",
__func__);
return 0;
}
} else
break;
}

return slot_mask;
}

static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
Expand Down Expand Up @@ -6941,7 +6966,9 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
*/
tdm->nslots_per_frame = tdm_group->nslots_per_frame;
tdm->slot_width = tdm_group->slot_width;
tdm->slot_mask = tdm_group->slot_mask;
tdm->slot_mask = tdm_param_set_slot_mask(slot_mapping->offset,
tdm_group->slot_width,
tdm_group->nslots_per_frame);

pr_debug("%s: TDM:\n"
"num_channels=%d sample_rate=%d bit_width=%d\n"
Expand Down
128 changes: 114 additions & 14 deletions techpack/audio/asoc/msm-pcm-q6-v2.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
Expand Down Expand Up @@ -582,8 +582,17 @@ static int msm_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
pr_debug("%s: Trigger start\n", __func__);
ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
if (prtd->qtime_lsw) {
pr_debug("%s: Trigger start at msw: %u, lsw: %u msec",
__func__, prtd->qtime_msw, prtd->qtime_lsw);
ret = q6asm_run_nowait(prtd->audio_client, 1,
prtd->qtime_msw, prtd->qtime_lsw);
prtd->qtime_lsw = 0;
prtd->qtime_msw = 0;
} else {
pr_debug("%s: Trigger start\n", __func__);
ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
}
break;
case SNDRV_PCM_TRIGGER_STOP:
pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
Expand Down Expand Up @@ -1118,7 +1127,8 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}

substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
substream = pdata->pcm[kcontrol->private_value]->
streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
ret = -EINVAL;
Expand Down Expand Up @@ -1403,7 +1413,8 @@ static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol,
pr_err("%s pdata is NULL\n", __func__);
return -ENODEV;
}
substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
substream = pdata->pcm[kcontrol->private_value]->
streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
return -EINVAL;
Expand Down Expand Up @@ -1433,7 +1444,8 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol,
pr_err("%s pdata is NULL\n", __func__);
return -ENODEV;
}
substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
substream = pdata->pcm[kcontrol->private_value]->
streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
pr_debug("%s: compress : 0x%x\n", __func__, compress);
if (!substream) {
pr_err("%s substream not found\n", __func__);
Expand Down Expand Up @@ -1493,15 +1505,13 @@ static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd)
pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
pdata = dev_get_drvdata(rtd->platform->dev);
if (pdata) {
if (!pdata->pcm) {
pdata->pcm = rtd->pcm;
snd_soc_add_platform_controls(rtd->platform,
pcm_compress_control,
ARRAY_SIZE
(pcm_compress_control));
pr_debug("%s: add control success plt = %pK\n",
pdata->pcm[rtd->dai_link->id] = rtd->pcm;
snd_soc_add_platform_controls(rtd->platform,
pcm_compress_control,
ARRAY_SIZE
(pcm_compress_control));
pr_debug("%s: add control success plt = %pK\n",
__func__, rtd->platform);
}
} else {
pr_err("%s: NULL pdata\n", __func__);
ret = -EINVAL;
Expand Down Expand Up @@ -1755,6 +1765,90 @@ static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
return 0;
}

static int msm_pcm_qtimer_ctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 0x200000;
return 0;
}

static int msm_pcm_qtimer_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
struct snd_pcm_substream *substream;
struct msm_audio *prtd;

if (!pdata) {
pr_err("%s pdata is NULL\n", __func__);
return -ENODEV;
}

substream = pdata->pcm[kcontrol->private_value]->
streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
return -EINVAL;
}

if (!substream->runtime) {
pr_err("%s substream runtime not found\n", __func__);
return 0;
}

prtd = substream->runtime->private_data;
if (prtd) {
prtd->qtime_lsw = ucontrol->value.integer.value[0];
prtd->qtime_msw = ucontrol->value.integer.value[1];
}

return 0;
}

static int msm_pcm_add_qtimer_control(struct snd_soc_pcm_runtime *rtd)
{
const char *mixer_ctl_name = "QTimer";
const char *deviceNo = "NN";
char *mixer_str = NULL;
int ctl_len = 0, ret = 0;
struct snd_kcontrol_new qtimer_control[1] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "?",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = msm_pcm_qtimer_ctl_info,
.put = msm_pcm_qtimer_ctl_put,
.private_value = 0,
}
};

ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
mixer_str = kzalloc(ctl_len, GFP_KERNEL);
if (!mixer_str) {
ret = -ENOMEM;
goto done;
}

snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
qtimer_control[0].name = mixer_str;
qtimer_control[0].private_value = rtd->dai_link->id;
ret = snd_soc_add_platform_controls(rtd->platform,
qtimer_control,
ARRAY_SIZE(qtimer_control));
if (ret < 0)
pr_err("%s: failed add ctl %s. err = %d\n",
__func__, mixer_str, ret);

kfree(mixer_str);
done:
return ret;
}

static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
Expand All @@ -1767,6 +1861,12 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
if (ret)
pr_err("%s: pcm add app type controls failed:%d\n",
__func__, ret);

ret = msm_pcm_add_qtimer_control(rtd);
if (ret)
pr_err("%s: pcm add qtimer controls failed:%d\n",
__func__, ret);

return ret;
}

Expand Down
9 changes: 5 additions & 4 deletions techpack/audio/asoc/msm-pcm-q6-v2.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
* Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2017,2019 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
Expand All @@ -20,8 +20,7 @@
#define _MSM_PCM_H
#include <dsp/apr_audio-v2.h>
#include <dsp/q6asm-v2.h>


#include "msm-pcm-routing-v2.h"

/* Support unconventional sample rates 12000, 24000 as well */
#define USE_RATE \
Expand Down Expand Up @@ -110,6 +109,8 @@ struct msm_audio {
bool meta_data_mode;
uint32_t volume;
bool compress_enable;
uint32_t qtime_lsw;
uint32_t qtime_msw;
/* array of frame info */
struct msm_audio_in_frame_info in_frame_info[CAPTURE_MAX_NUM_PERIODS];
};
Expand All @@ -124,7 +125,7 @@ struct output_meta_data_st {

struct msm_plat_data {
int perf_mode;
struct snd_pcm *pcm;
struct snd_pcm *pcm[MSM_FRONTEND_DAI_MAX];
};

#endif /*_MSM_PCM_H*/
Loading

0 comments on commit 656fac7

Please sign in to comment.