ASoC: msm: qdsp6v2: Extend LSM support to 48khz, 24bit and 4 channel
Enhance LSM code to support maximum configuration of 48khz, 24bit and 4 channel. Change-Id: I03895c983527d87389ca69e85235b1def5b4a2fa Signed-off-by: Chaithanya Krishna Bacharaju <chaithan@codeaurora.org> Signed-off-by: Revathi Uddaraju <revathiu@codeaurora.org>
This commit is contained in:
parent
1f5681eec2
commit
f7b4f38b89
5 changed files with 202 additions and 54 deletions
|
@ -9063,6 +9063,7 @@ struct asm_aptx_dec_fmt_blk_v2 {
|
|||
#define LSM_PARAM_ID_SWMAD_MODEL (0x00012C19)
|
||||
#define LSM_PARAM_ID_SWMAD_ENABLE (0x00012C1A)
|
||||
#define LSM_PARAM_ID_POLLING_ENABLE (0x00012C1B)
|
||||
#define LSM_PARAM_ID_MEDIA_FMT (0x00012C1E)
|
||||
#define LSM_PARAM_ID_FWK_MODE_CONFIG (0x00012C27)
|
||||
|
||||
/* HW MAD specific */
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#define ADM_LSM_PORT_ID 0xADCB
|
||||
|
||||
#define LSM_MAX_NUM_CHANNELS 8
|
||||
|
||||
typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token,
|
||||
uint32_t *payload, void *priv);
|
||||
|
||||
|
@ -51,11 +53,12 @@ struct lsm_lab_buffer {
|
|||
uint32_t mem_map_handle;
|
||||
};
|
||||
|
||||
struct lsm_lab_hw_params {
|
||||
struct lsm_hw_params {
|
||||
u16 sample_rate;
|
||||
u16 sample_size;
|
||||
u32 buf_sz;
|
||||
u32 period_count;
|
||||
u16 num_chs;
|
||||
};
|
||||
|
||||
struct lsm_client {
|
||||
|
@ -81,7 +84,7 @@ struct lsm_client {
|
|||
bool lab_enable;
|
||||
bool lab_started;
|
||||
struct lsm_lab_buffer *lab_buffer;
|
||||
struct lsm_lab_hw_params hw_params;
|
||||
struct lsm_hw_params hw_params;
|
||||
bool use_topology;
|
||||
int session_state;
|
||||
bool poll_enable;
|
||||
|
@ -153,6 +156,15 @@ struct lsm_param_fwk_mode_cfg {
|
|||
uint32_t mode;
|
||||
} __packed;
|
||||
|
||||
struct lsm_param_media_fmt {
|
||||
struct lsm_param_payload_common common;
|
||||
uint32_t minor_version;
|
||||
uint32_t sample_rate;
|
||||
uint16_t num_channels;
|
||||
uint16_t bit_width;
|
||||
uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* This param cannot be sent in this format.
|
||||
* The actual number of confidence level values
|
||||
|
@ -285,6 +297,13 @@ struct lsm_cmd_set_fwk_mode_cfg {
|
|||
struct lsm_param_fwk_mode_cfg fwk_mode_cfg;
|
||||
} __packed;
|
||||
|
||||
struct lsm_cmd_set_media_fmt {
|
||||
struct apr_hdr msg_hdr;
|
||||
struct lsm_set_params_hdr params_hdr;
|
||||
struct lsm_param_media_fmt media_fmt;
|
||||
} __packed;
|
||||
|
||||
|
||||
struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv);
|
||||
void q6lsm_client_free(struct lsm_client *client);
|
||||
int q6lsm_open(struct lsm_client *client, uint16_t app_id);
|
||||
|
@ -315,4 +334,5 @@ void q6lsm_sm_set_param_data(struct lsm_client *client,
|
|||
size_t *offset);
|
||||
int q6lsm_set_port_connected(struct lsm_client *client);
|
||||
int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode);
|
||||
int q6lsm_set_media_fmt_params(struct lsm_client *client);
|
||||
#endif /* __Q6LSM_H__ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2017, 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
|
||||
|
@ -2203,12 +2203,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 1 Audio Service Capture",
|
||||
.aif_name = "LSM1_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM1",
|
||||
|
@ -2218,12 +2220,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 2 Audio Service Capture",
|
||||
.aif_name = "LSM2_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM2",
|
||||
|
@ -2233,12 +2237,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 3 Audio Service Capture",
|
||||
.aif_name = "LSM3_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM3",
|
||||
|
@ -2248,12 +2254,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 4 Audio Service Capture",
|
||||
.aif_name = "LSM4_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM4",
|
||||
|
@ -2263,12 +2271,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 5 Audio Service Capture",
|
||||
.aif_name = "LSM5_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM5",
|
||||
|
@ -2278,12 +2288,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 6 Audio Service Capture",
|
||||
.aif_name = "LSM6_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM6",
|
||||
|
@ -2293,12 +2305,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 7 Audio Service Capture",
|
||||
.aif_name = "LSM7_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM7",
|
||||
|
@ -2308,12 +2322,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
|
|||
.capture = {
|
||||
.stream_name = "Listen 8 Audio Service Capture",
|
||||
.aif_name = "LSM8_UL_HL",
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
},
|
||||
.ops = &msm_fe_dai_ops,
|
||||
.name = "LSM8",
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#define CAPTURE_MIN_NUM_PERIODS 2
|
||||
#define CAPTURE_MAX_NUM_PERIODS 8
|
||||
#define CAPTURE_MAX_PERIOD_SIZE 4096
|
||||
#define CAPTURE_MAX_PERIOD_SIZE 61440
|
||||
#define CAPTURE_MIN_PERIOD_SIZE 320
|
||||
#define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256
|
||||
|
||||
|
@ -47,12 +47,14 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
|
|||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_16000,
|
||||
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE),
|
||||
.rates = (SNDRV_PCM_RATE_16000 |
|
||||
SNDRV_PCM_RATE_48000),
|
||||
.rate_min = 16000,
|
||||
.rate_max = 16000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.channels_max = 4,
|
||||
.buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
|
||||
CAPTURE_MAX_PERIOD_SIZE,
|
||||
.period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
|
||||
|
@ -64,7 +66,7 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
|
|||
|
||||
/* Conventional and unconventional sample rate supported */
|
||||
static unsigned int supported_sample_rates[] = {
|
||||
16000,
|
||||
16000, 48000,
|
||||
};
|
||||
|
||||
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
|
||||
|
@ -1962,6 +1964,10 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (q6lsm_set_media_fmt_params(prtd->lsm_client))
|
||||
dev_dbg(rtd->dev,
|
||||
"%s: failed to set lsm media fmt params\n", __func__);
|
||||
|
||||
if (prtd->lsm_client->session_state == IDLE) {
|
||||
ret = msm_pcm_routing_reg_phy_compr_stream(
|
||||
rtd->dai_link->be_id,
|
||||
|
@ -2053,7 +2059,7 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct lsm_priv *prtd = runtime->private_data;
|
||||
struct lsm_lab_hw_params *hw_params = NULL;
|
||||
struct lsm_hw_params *hw_params = NULL;
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
|
||||
if (!substream->private_data) {
|
||||
|
@ -2069,25 +2075,36 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
hw_params = &prtd->lsm_client->hw_params;
|
||||
hw_params->sample_rate = params_rate(params);
|
||||
hw_params->sample_size =
|
||||
(params_format(params) == SNDRV_PCM_FORMAT_S16_LE) ? 16 : 0;
|
||||
hw_params->num_chs = params_channels(params);
|
||||
hw_params->period_count = params_periods(params);
|
||||
if (hw_params->sample_rate != 16000 || hw_params->sample_size != 16 ||
|
||||
hw_params->period_count == 0) {
|
||||
hw_params->sample_rate = params_rate(params);
|
||||
if (((hw_params->sample_rate != 16000) &&
|
||||
(hw_params->sample_rate != 48000)) ||
|
||||
(hw_params->period_count == 0)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: Invalid params sample rate %d sample size %d period count %d",
|
||||
"%s: Invalid Params sample rate %d period count %d\n",
|
||||
__func__, hw_params->sample_rate,
|
||||
hw_params->sample_size,
|
||||
hw_params->period_count);
|
||||
hw_params->period_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) {
|
||||
hw_params->sample_size = 16;
|
||||
} else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) {
|
||||
hw_params->sample_size = 24;
|
||||
} else {
|
||||
dev_err(rtd->dev, "%s: Invalid Format 0x%x\n",
|
||||
__func__, params_format(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hw_params->buf_sz = params_buffer_bytes(params) /
|
||||
hw_params->period_count;
|
||||
hw_params->period_count;
|
||||
dev_dbg(rtd->dev,
|
||||
"%s: sample rate %d sample size %d buffer size %d period count %d\n",
|
||||
__func__, hw_params->sample_rate, hw_params->sample_size,
|
||||
hw_params->buf_sz, hw_params->period_count);
|
||||
"%s: channels %d sample rate %d sample size %d buffer size %d period count %d\n",
|
||||
__func__, hw_params->num_chs, hw_params->sample_rate,
|
||||
hw_params->sample_size, hw_params->buf_sz,
|
||||
hw_params->period_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#define LSM_ALIGN_BOUNDARY 512
|
||||
#define LSM_SAMPLE_RATE 16000
|
||||
#define QLSM_PARAM_ID_MINOR_VERSION 1
|
||||
#define QLSM_PARAM_ID_MINOR_VERSION_2 2
|
||||
|
||||
static int lsm_afe_port;
|
||||
|
||||
enum {
|
||||
|
@ -897,6 +899,98 @@ int q6lsm_set_fwk_mode_cfg(struct lsm_client *client,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt,
|
||||
int channel_count)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
memset(media_fmt->channel_mapping, 0, LSM_MAX_NUM_CHANNELS);
|
||||
|
||||
switch (channel_count) {
|
||||
case 1:
|
||||
media_fmt->channel_mapping[0] = PCM_CHANNEL_FC;
|
||||
break;
|
||||
case 2:
|
||||
media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
break;
|
||||
case 3:
|
||||
media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
media_fmt->channel_mapping[2] = PCM_CHANNEL_FC;
|
||||
break;
|
||||
case 4:
|
||||
media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
|
||||
media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
|
||||
media_fmt->channel_mapping[2] = PCM_CHANNEL_LS;
|
||||
media_fmt->channel_mapping[3] = PCM_CHANNEL_RS;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid num_chan %d\n", __func__, channel_count);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int q6lsm_set_media_fmt_params(struct lsm_client *client)
|
||||
{
|
||||
int rc = 0;
|
||||
struct lsm_cmd_set_media_fmt cmd;
|
||||
struct lsm_module_param_ids media_fmt_ids;
|
||||
struct apr_hdr *msg_hdr;
|
||||
struct lsm_param_media_fmt *media_fmt;
|
||||
u32 data_payload_size, param_size, set_param_opcode;
|
||||
struct lsm_hw_params param = client->hw_params;
|
||||
|
||||
if (client->use_topology) {
|
||||
set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
|
||||
media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
|
||||
media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT;
|
||||
} else {
|
||||
pr_debug("%s: Ignore sending media format\n", __func__);
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
msg_hdr = &cmd.msg_hdr;
|
||||
q6lsm_add_hdr(client, msg_hdr,
|
||||
sizeof(struct lsm_cmd_set_media_fmt), true);
|
||||
msg_hdr->opcode = set_param_opcode;
|
||||
data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) -
|
||||
sizeof(struct apr_hdr) -
|
||||
sizeof(struct lsm_set_params_hdr);
|
||||
q6lsm_set_param_hdr_info(&cmd.params_hdr,
|
||||
data_payload_size, 0, 0, 0);
|
||||
media_fmt = &cmd.media_fmt;
|
||||
|
||||
param_size = (sizeof(struct lsm_param_media_fmt) -
|
||||
sizeof(media_fmt->common));
|
||||
q6lsm_set_param_common(&media_fmt->common,
|
||||
&media_fmt_ids, param_size,
|
||||
set_param_opcode);
|
||||
|
||||
media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2;
|
||||
media_fmt->sample_rate = param.sample_rate;
|
||||
media_fmt->num_channels = param.num_chs;
|
||||
media_fmt->bit_width = param.sample_size;
|
||||
|
||||
rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels);
|
||||
if (rc)
|
||||
goto err_ret;
|
||||
|
||||
pr_debug("%s: sample rate= %d, channels %d bit width %d\n",
|
||||
__func__, media_fmt->sample_rate, media_fmt->num_channels,
|
||||
media_fmt->bit_width);
|
||||
|
||||
rc = q6lsm_apr_send_pkt(client, client->apr,
|
||||
&cmd, true, NULL);
|
||||
if (rc)
|
||||
pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
|
||||
__func__, msg_hdr->opcode, rc);
|
||||
err_ret:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int q6lsm_set_data(struct lsm_client *client,
|
||||
enum lsm_detection_mode mode,
|
||||
bool detectfailure)
|
||||
|
|
Loading…
Add table
Reference in a new issue