|
@@ -499,38 +499,71 @@ static int msm_lsm_get_conf_levels(struct lsm_client *client,
|
|
|
{
|
|
|
int rc = 0;
|
|
|
|
|
|
- if (client->num_confidence_levels == 0) {
|
|
|
- pr_debug("%s: no confidence levels provided\n",
|
|
|
- __func__);
|
|
|
- client->confidence_levels = NULL;
|
|
|
- goto done;
|
|
|
- }
|
|
|
+ if (client->num_sound_models != 0) {
|
|
|
+ if (client->num_keywords == 0) {
|
|
|
+ pr_debug("%s: no number of confidence_values provided\n",
|
|
|
+ __func__);
|
|
|
+ client->multi_snd_model_confidence_levels = NULL;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ client->multi_snd_model_confidence_levels =
|
|
|
+ kzalloc((sizeof(uint32_t) * client->num_keywords),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!client->multi_snd_model_confidence_levels) {
|
|
|
+ pr_err("%s: No memory for confidence\n"
|
|
|
+ "levels num of level from user = %d\n",
|
|
|
+ __func__, client->num_keywords);
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
|
|
|
- client->confidence_levels =
|
|
|
- kzalloc((sizeof(uint8_t) * client->num_confidence_levels),
|
|
|
- GFP_KERNEL);
|
|
|
- if (!client->confidence_levels) {
|
|
|
- pr_err("%s: No memory for confidence\n"
|
|
|
- "levels num of level from user = %d\n",
|
|
|
- __func__, client->num_confidence_levels);
|
|
|
- rc = -ENOMEM;
|
|
|
+ if (copy_from_user((u8 *)client->multi_snd_model_confidence_levels,
|
|
|
+ conf_levels_ptr,
|
|
|
+ sizeof(uint32_t) * client->num_keywords)) {
|
|
|
+ pr_err("%s: copy from user failed, number of keywords = %d\n",
|
|
|
+ __func__, client->num_keywords);
|
|
|
+ rc = -EFAULT;
|
|
|
+ goto copy_err;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (client->num_confidence_levels == 0) {
|
|
|
+ pr_debug("%s: no confidence levels provided\n",
|
|
|
+ __func__);
|
|
|
+ client->confidence_levels = NULL;
|
|
|
goto done;
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- if (copy_from_user(client->confidence_levels,
|
|
|
- conf_levels_ptr,
|
|
|
- client->num_confidence_levels)) {
|
|
|
- pr_err("%s: copy from user failed, size = %d\n",
|
|
|
- __func__, client->num_confidence_levels);
|
|
|
- rc = -EFAULT;
|
|
|
- goto copy_err;
|
|
|
- }
|
|
|
+ client->confidence_levels =
|
|
|
+ kzalloc((sizeof(uint8_t) * client->num_confidence_levels),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!client->confidence_levels) {
|
|
|
+ pr_err("%s: No memory for confidence\n"
|
|
|
+ "levels num of level from user = %d\n",
|
|
|
+ __func__, client->num_confidence_levels);
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
|
|
|
+ if (copy_from_user(client->confidence_levels,
|
|
|
+ conf_levels_ptr,
|
|
|
+ client->num_confidence_levels)) {
|
|
|
+ pr_err("%s: copy from user failed, size = %d\n",
|
|
|
+ __func__, client->num_confidence_levels);
|
|
|
+ rc = -EFAULT;
|
|
|
+ goto copy_err;
|
|
|
+ }
|
|
|
+ }
|
|
|
return rc;
|
|
|
|
|
|
copy_err:
|
|
|
- kfree(client->confidence_levels);
|
|
|
- client->confidence_levels = NULL;
|
|
|
+ if (client->num_sound_models != 0) {
|
|
|
+ kfree(client->multi_snd_model_confidence_levels);
|
|
|
+ client->multi_snd_model_confidence_levels = NULL;
|
|
|
+ } else {
|
|
|
+ kfree(client->confidence_levels);
|
|
|
+ client->confidence_levels = NULL;
|
|
|
+ }
|
|
|
done:
|
|
|
return rc;
|
|
|
|
|
@@ -652,35 +685,67 @@ static int msm_lsm_set_conf(struct snd_pcm_substream *substream,
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
int rc = 0;
|
|
|
|
|
|
- if (p_info->param_size > MAX_NUM_CONFIDENCE) {
|
|
|
- dev_err(rtd->dev,
|
|
|
- "%s: invalid confidence levels %d\n",
|
|
|
- __func__, p_info->param_size);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+ if (p_info->param_type == LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS) {
|
|
|
+ if (p_info->param_size > MAX_KEYWORDS_SUPPORTED) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: invalid number of snd_model keywords %d, the max is %d\n",
|
|
|
+ __func__, p_info->param_size, MAX_KEYWORDS_SUPPORTED);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- prtd->lsm_client->num_confidence_levels =
|
|
|
- p_info->param_size;
|
|
|
- rc = msm_lsm_get_conf_levels(prtd->lsm_client,
|
|
|
- p_info->param_data);
|
|
|
- if (rc) {
|
|
|
- dev_err(rtd->dev,
|
|
|
- "%s: get_conf_levels failed, err = %d\n",
|
|
|
- __func__, rc);
|
|
|
- return rc;
|
|
|
- }
|
|
|
+ prtd->lsm_client->num_keywords = p_info->param_size;
|
|
|
+ rc = msm_lsm_get_conf_levels(prtd->lsm_client,
|
|
|
+ p_info->param_data);
|
|
|
+ if (rc) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: get_conf_levels failed for snd_model %d, err = %d\n",
|
|
|
+ __func__, p_info->model_id, rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
|
|
|
- rc = q6lsm_set_one_param(prtd->lsm_client, p_info,
|
|
|
- prtd->lsm_client->confidence_levels,
|
|
|
- LSM_MIN_CONFIDENCE_LEVELS);
|
|
|
- if (rc)
|
|
|
- dev_err(rtd->dev,
|
|
|
- "%s: Failed to set min_conf_levels, err = %d\n",
|
|
|
- __func__, rc);
|
|
|
+ rc = q6lsm_set_one_param(prtd->lsm_client, p_info,
|
|
|
+ prtd->lsm_client->multi_snd_model_confidence_levels,
|
|
|
+ LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS);
|
|
|
+ if (rc)
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: Failed to set multi_snd_model_confidence_levels, err = %d\n",
|
|
|
+ __func__, rc);
|
|
|
|
|
|
- if (prtd->lsm_client->confidence_levels) {
|
|
|
- kfree(prtd->lsm_client->confidence_levels);
|
|
|
- prtd->lsm_client->confidence_levels = NULL;
|
|
|
+ if (prtd->lsm_client->multi_snd_model_confidence_levels) {
|
|
|
+ kfree(prtd->lsm_client->multi_snd_model_confidence_levels);
|
|
|
+ prtd->lsm_client->multi_snd_model_confidence_levels = NULL;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (p_info->param_size > MAX_NUM_CONFIDENCE) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: invalid confidence levels %d\n",
|
|
|
+ __func__, p_info->param_size);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ prtd->lsm_client->num_confidence_levels =
|
|
|
+ p_info->param_size;
|
|
|
+ rc = msm_lsm_get_conf_levels(prtd->lsm_client,
|
|
|
+ p_info->param_data);
|
|
|
+ if (rc) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: get_conf_levels failed, err = %d\n",
|
|
|
+ __func__, rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = q6lsm_set_one_param(prtd->lsm_client, p_info,
|
|
|
+ prtd->lsm_client->confidence_levels,
|
|
|
+ LSM_MIN_CONFIDENCE_LEVELS);
|
|
|
+ if (rc)
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: Failed to set min_conf_levels, err = %d\n",
|
|
|
+ __func__, rc);
|
|
|
+
|
|
|
+ if (prtd->lsm_client->confidence_levels) {
|
|
|
+ kfree(prtd->lsm_client->confidence_levels);
|
|
|
+ prtd->lsm_client->confidence_levels = NULL;
|
|
|
+ }
|
|
|
}
|
|
|
return rc;
|
|
|
}
|
|
@@ -691,66 +756,166 @@ static int msm_lsm_reg_model(struct snd_pcm_substream *substream,
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
struct lsm_priv *prtd = runtime->private_data;
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
- int rc = 0;
|
|
|
+ int rc = 0, stage_idx = p_info->stage_idx;
|
|
|
struct lsm_sound_model *sm = NULL;
|
|
|
size_t offset = sizeof(union param_hdrs);
|
|
|
+ struct lsm_client *client = prtd->lsm_client;
|
|
|
|
|
|
- rc = q6lsm_snd_model_buf_alloc(prtd->lsm_client,
|
|
|
- p_info->param_size, p_info);
|
|
|
- if (rc) {
|
|
|
- dev_err(rtd->dev,
|
|
|
- "%s: snd_model buf alloc failed, size = %d\n",
|
|
|
- __func__, p_info->param_size);
|
|
|
- return rc;
|
|
|
- }
|
|
|
+ if (p_info->model_id != 0 &&
|
|
|
+ p_info->param_type == LSM_REG_MULTI_SND_MODEL) {
|
|
|
+ sm = kzalloc(sizeof(*sm), GFP_KERNEL);
|
|
|
+ if (sm == NULL) {
|
|
|
+ dev_err(rtd->dev, "%s: snd_model kzalloc failed\n", __func__);
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
|
|
|
- q6lsm_sm_set_param_data(prtd->lsm_client, p_info, &offset);
|
|
|
+ INIT_LIST_HEAD(&sm->list);
|
|
|
|
|
|
- /*
|
|
|
- * For set_param, advance the sound model data with the
|
|
|
- * number of bytes required by param_data.
|
|
|
- */
|
|
|
+ rc = q6lsm_snd_model_buf_alloc(client, p_info->param_size, p_info, sm);
|
|
|
+ if (rc) {
|
|
|
+ dev_err(rtd->dev, "%s: snd_model buf alloc failed, size = %d\n",
|
|
|
+ __func__, p_info->param_size);
|
|
|
+ goto err_buf_alloc;
|
|
|
+ }
|
|
|
|
|
|
- sm = &prtd->lsm_client->stage_cfg[p_info->stage_idx].sound_model;
|
|
|
- if (copy_from_user((u8 *)sm->data + offset,
|
|
|
- p_info->param_data, p_info->param_size)) {
|
|
|
- dev_err(rtd->dev,
|
|
|
- "%s: copy_from_user for snd_model failed, size = %d\n",
|
|
|
- __func__, p_info->param_size);
|
|
|
- rc = -EFAULT;
|
|
|
- goto err_copy;
|
|
|
- }
|
|
|
- rc = q6lsm_set_one_param(prtd->lsm_client, p_info, NULL,
|
|
|
- LSM_REG_SND_MODEL);
|
|
|
- if (rc) {
|
|
|
+ q6lsm_sm_set_param_data(client, p_info, &offset, sm);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * For set_param, advance the sound model data with the
|
|
|
+ * number of bytes required by param_data.
|
|
|
+ */
|
|
|
+ if (copy_from_user((u8 *)sm->data + offset,
|
|
|
+ p_info->param_data, p_info->param_size)) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: copy_from_user for snd_model %d failed, size = %d\n",
|
|
|
+ __func__, p_info->model_id, p_info->param_size);
|
|
|
+ rc = -EFAULT;
|
|
|
+ goto err_copy;
|
|
|
+ }
|
|
|
+ /* Add this sound model to the list of multi sound models */
|
|
|
+ list_add_tail(&sm->list, &client->stage_cfg[stage_idx].sound_models);
|
|
|
+
|
|
|
+ rc = q6lsm_set_one_param(client, p_info, NULL,
|
|
|
+ LSM_REG_MULTI_SND_MODEL);
|
|
|
+ if (rc) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: Failed to register snd_model %d, err = %d\n",
|
|
|
+ __func__, p_info->model_id, rc);
|
|
|
+ goto err_copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ client->num_sound_models++;
|
|
|
+ dev_dbg(rtd->dev,
|
|
|
+ "%s: registered snd_model: %d, total num of snd_model: %d\n",
|
|
|
+ __func__, p_info->model_id, client->num_sound_models);
|
|
|
+ } else if (p_info->model_id == 0 &&
|
|
|
+ p_info->param_type == LSM_REG_SND_MODEL) {
|
|
|
+ sm = &client->stage_cfg[stage_idx].sound_model;
|
|
|
+
|
|
|
+ rc = q6lsm_snd_model_buf_alloc(client, p_info->param_size, p_info, sm);
|
|
|
+ if (rc) {
|
|
|
+ dev_err(rtd->dev, "%s: snd_model buf alloc failed, size = %d\n",
|
|
|
+ __func__, p_info->param_size);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ q6lsm_sm_set_param_data(client, p_info, &offset, sm);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * For set_param, advance the sound model data with the
|
|
|
+ * number of bytes required by param_data.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (copy_from_user((u8 *)sm->data + offset,
|
|
|
+ p_info->param_data, p_info->param_size)) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: copy_from_user for snd_model failed, size = %d\n",
|
|
|
+ __func__, p_info->param_size);
|
|
|
+ rc = -EFAULT;
|
|
|
+ goto err_copy;
|
|
|
+ }
|
|
|
+ rc = q6lsm_set_one_param(client, p_info, NULL, LSM_REG_SND_MODEL);
|
|
|
+ if (rc) {
|
|
|
+ dev_err(rtd->dev, "%s: Failed to register snd_model, err = %d\n",
|
|
|
+ __func__, rc);
|
|
|
+ goto err_copy;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
dev_err(rtd->dev,
|
|
|
- "%s: Failed to set sound_model, err = %d\n",
|
|
|
- __func__, rc);
|
|
|
- goto err_copy;
|
|
|
+ "%s: snd_model id %d is invalid for param type %d\n",
|
|
|
+ __func__, p_info->model_id, p_info->param_type);
|
|
|
}
|
|
|
return rc;
|
|
|
|
|
|
err_copy:
|
|
|
- q6lsm_snd_model_buf_free(prtd->lsm_client, p_info);
|
|
|
+ q6lsm_snd_model_buf_free(client, p_info, sm);
|
|
|
+err_buf_alloc:
|
|
|
+ if (p_info->model_id != 0) {
|
|
|
+ list_del(&sm->list);
|
|
|
+ kfree(sm);
|
|
|
+ sm = NULL;
|
|
|
+ }
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
static int msm_lsm_dereg_model(struct snd_pcm_substream *substream,
|
|
|
- struct lsm_params_info_v2 *p_info)
|
|
|
+ struct lsm_params_info_v2 *p_info)
|
|
|
{
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
struct lsm_priv *prtd = runtime->private_data;
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
+ struct lsm_sound_model *sm = NULL;
|
|
|
+ struct lsm_client *client = prtd->lsm_client;
|
|
|
int rc = 0;
|
|
|
|
|
|
- rc = q6lsm_set_one_param(prtd->lsm_client, p_info,
|
|
|
- NULL, LSM_DEREG_SND_MODEL);
|
|
|
- if (rc)
|
|
|
- dev_err(rtd->dev,
|
|
|
- "%s: Failed to set det_mode param, err = %d\n",
|
|
|
- __func__, rc);
|
|
|
+ if (p_info->model_id != 0 &&
|
|
|
+ p_info->param_type == LSM_DEREG_MULTI_SND_MODEL) {
|
|
|
+ list_for_each_entry(sm,
|
|
|
+ &client->stage_cfg[p_info->stage_idx].sound_models,
|
|
|
+ list) {
|
|
|
+ dev_dbg(rtd->dev,
|
|
|
+ "%s: current snd_model: %d, looking for snd_model %d\n",
|
|
|
+ __func__, sm->model_id, p_info->model_id);
|
|
|
+ if (sm->model_id == p_info->model_id)
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- q6lsm_snd_model_buf_free(prtd->lsm_client, p_info);
|
|
|
+ if (sm->model_id == p_info->model_id) {
|
|
|
+ rc = q6lsm_set_one_param(client, p_info, NULL,
|
|
|
+ LSM_DEREG_MULTI_SND_MODEL);
|
|
|
+ if (rc)
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: Failed to deregister snd_model %d, err = %d\n",
|
|
|
+ __func__, p_info->model_id, rc);
|
|
|
+
|
|
|
+ q6lsm_snd_model_buf_free(client, p_info, sm);
|
|
|
+ list_del(&sm->list);
|
|
|
+ kfree(sm);
|
|
|
+ sm = NULL;
|
|
|
+ client->num_sound_models--;
|
|
|
+ } else {
|
|
|
+ rc = -EINVAL;
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: Failed to find snd_model, invalid model_id %d\n",
|
|
|
+ __func__, p_info->model_id);
|
|
|
+ }
|
|
|
+ } else if (p_info->model_id == 0 &&
|
|
|
+ p_info->param_type == LSM_DEREG_SND_MODEL) {
|
|
|
+ rc = q6lsm_set_one_param(client, p_info, NULL,
|
|
|
+ LSM_DEREG_SND_MODEL);
|
|
|
+ if (rc)
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: Failed to deregister snd_model, err = %d\n",
|
|
|
+ __func__, rc);
|
|
|
+
|
|
|
+ sm = &client->stage_cfg[p_info->stage_idx].sound_model;
|
|
|
+ q6lsm_snd_model_buf_free(client, p_info, sm);
|
|
|
+ } else {
|
|
|
+ rc = -EINVAL;
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: snd_model id %d is invalid for param type %d\n",
|
|
|
+ __func__, p_info->model_id, p_info->param_type);
|
|
|
+ }
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -992,6 +1157,22 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ if (p_info->param_type == LSM_REG_MULTI_SND_MODEL &&
|
|
|
+ prtd->lsm_client->num_sound_models == LSM_MAX_SOUND_MODELS_SUPPORTED) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: maximum supported sound models(8) have already reached\n",
|
|
|
+ __func__);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (p_info->param_type == LSM_DEREG_MULTI_SND_MODEL &&
|
|
|
+ prtd->lsm_client->num_sound_models == 0) {
|
|
|
+ dev_err(rtd->dev,
|
|
|
+ "%s: no available sound model to be deregistered\n",
|
|
|
+ __func__);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
switch (p_info->param_type) {
|
|
|
case LSM_ENDPOINT_DETECT_THRESHOLD:
|
|
|
rc = msm_lsm_set_epd(substream, p_info);
|
|
@@ -1003,12 +1184,15 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream,
|
|
|
rc = msm_lsm_set_gain(substream, p_info);
|
|
|
break;
|
|
|
case LSM_MIN_CONFIDENCE_LEVELS:
|
|
|
+ case LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS:
|
|
|
rc = msm_lsm_set_conf(substream, p_info);
|
|
|
break;
|
|
|
case LSM_REG_SND_MODEL:
|
|
|
+ case LSM_REG_MULTI_SND_MODEL:
|
|
|
rc = msm_lsm_reg_model(substream, p_info);
|
|
|
break;
|
|
|
case LSM_DEREG_SND_MODEL:
|
|
|
+ case LSM_DEREG_MULTI_SND_MODEL:
|
|
|
rc = msm_lsm_dereg_model(substream, p_info);
|
|
|
break;
|
|
|
case LSM_CUSTOM_PARAMS:
|
|
@@ -1176,7 +1360,10 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
|
|
|
* also set stage index to LSM_STAGE_INDEX_FIRST.
|
|
|
*/
|
|
|
struct lsm_params_info_v2 p_info = {0};
|
|
|
+ struct lsm_sound_model *sm = NULL;
|
|
|
p_info.stage_idx = LSM_STAGE_INDEX_FIRST;
|
|
|
+ p_info.param_type = LSM_DEREG_SND_MODEL;
|
|
|
+ sm = &prtd->lsm_client->stage_cfg[p_info.stage_idx].sound_model;
|
|
|
|
|
|
dev_dbg(rtd->dev, "%s: Registering sound model V2\n",
|
|
|
__func__);
|
|
@@ -1192,21 +1379,20 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
|
|
|
break;
|
|
|
}
|
|
|
rc = q6lsm_snd_model_buf_alloc(prtd->lsm_client,
|
|
|
- snd_model_v2.data_size, &p_info);
|
|
|
+ snd_model_v2.data_size, &p_info, sm);
|
|
|
if (rc) {
|
|
|
dev_err(rtd->dev,
|
|
|
"%s: q6lsm buffer alloc failed V2, size %d\n",
|
|
|
__func__, snd_model_v2.data_size);
|
|
|
break;
|
|
|
}
|
|
|
- if (copy_from_user(
|
|
|
- prtd->lsm_client->stage_cfg[p_info.stage_idx].sound_model.data,
|
|
|
- snd_model_v2.data, snd_model_v2.data_size)) {
|
|
|
+ if (copy_from_user(sm->data, snd_model_v2.data,
|
|
|
+ snd_model_v2.data_size)) {
|
|
|
dev_err(rtd->dev,
|
|
|
"%s: copy from user data failed\n"
|
|
|
"data %pK size %d\n", __func__,
|
|
|
snd_model_v2.data, snd_model_v2.data_size);
|
|
|
- q6lsm_snd_model_buf_free(prtd->lsm_client, &p_info);
|
|
|
+ q6lsm_snd_model_buf_free(prtd->lsm_client, &p_info, sm);
|
|
|
rc = -EFAULT;
|
|
|
break;
|
|
|
}
|
|
@@ -1234,7 +1420,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
|
|
|
dev_err(rtd->dev,
|
|
|
"%s: Register snd Model v2 failed =%d\n",
|
|
|
__func__, rc);
|
|
|
- q6lsm_snd_model_buf_free(prtd->lsm_client, &p_info);
|
|
|
+ q6lsm_snd_model_buf_free(prtd->lsm_client, &p_info, sm);
|
|
|
}
|
|
|
if (prtd->lsm_client->confidence_levels) {
|
|
|
kfree(prtd->lsm_client->confidence_levels);
|
|
@@ -1697,6 +1883,7 @@ struct lsm_params_info_v2_32 {
|
|
|
uint32_t param_type;
|
|
|
u16 instance_id;
|
|
|
u16 stage_idx;
|
|
|
+ u32 model_id;
|
|
|
};
|
|
|
|
|
|
struct snd_lsm_module_params_32 {
|
|
@@ -2033,9 +2220,9 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
|
|
|
|
|
|
if (p_data.data_size != expected_size) {
|
|
|
dev_err(rtd->dev,
|
|
|
- "%s: %s: Invalid size %d\n",
|
|
|
+ "%s: %s: Invalid size %d, expected_size %d\n",
|
|
|
__func__, "SET_MODULE_PARAMS(_V2)_32",
|
|
|
- p_data.data_size);
|
|
|
+ p_data.data_size, expected_size);
|
|
|
err = -EINVAL;
|
|
|
goto done;
|
|
|
}
|
|
@@ -2071,6 +2258,7 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
|
|
|
|
|
|
p_info.instance_id = INSTANCE_ID_0;
|
|
|
p_info.stage_idx = LSM_STAGE_INDEX_FIRST;
|
|
|
+ p_info.model_id = 0;
|
|
|
|
|
|
p_info_32++;
|
|
|
} else {
|
|
@@ -2082,6 +2270,14 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
|
|
|
|
|
|
p_info.instance_id = p_info_v2_32->instance_id;
|
|
|
p_info.stage_idx = p_info_v2_32->stage_idx;
|
|
|
+ /* set sound model id to 0 for backward compatibility */
|
|
|
+ p_info.model_id = 0;
|
|
|
+
|
|
|
+ if (LSM_REG_MULTI_SND_MODEL == p_info_v2_32->param_type ||
|
|
|
+ LSM_DEREG_MULTI_SND_MODEL == p_info_v2_32->param_type ||
|
|
|
+ LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS ==
|
|
|
+ p_info_v2_32->param_type)
|
|
|
+ p_info.model_id = p_info_v2_32->model_id;
|
|
|
|
|
|
p_info_v2_32++;
|
|
|
}
|
|
@@ -2208,7 +2404,6 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream,
|
|
|
case SNDRV_LSM_SET_MODULE_PARAMS_V2: {
|
|
|
struct snd_lsm_module_params p_data;
|
|
|
struct lsm_params_info *temp_ptr_info = NULL;
|
|
|
- struct lsm_params_info_v2 info_v2;
|
|
|
struct lsm_params_info_v2 *ptr_info_v2 = NULL, *temp_ptr_info_v2 = NULL;
|
|
|
size_t p_size = 0, count;
|
|
|
u8 *params;
|
|
@@ -2277,26 +2472,37 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream,
|
|
|
for (count = 0; count < p_data.num_params; count++) {
|
|
|
if (cmd == SNDRV_LSM_SET_MODULE_PARAMS) {
|
|
|
/* convert to V2 param info struct from legacy param info */
|
|
|
- info_v2.module_id = temp_ptr_info->module_id;
|
|
|
- info_v2.param_id = temp_ptr_info->param_id;
|
|
|
- info_v2.param_size = temp_ptr_info->param_size;
|
|
|
- info_v2.param_data = temp_ptr_info->param_data;
|
|
|
- info_v2.param_type = temp_ptr_info->param_type;
|
|
|
+ ptr_info_v2->module_id = temp_ptr_info->module_id;
|
|
|
+ ptr_info_v2->param_id = temp_ptr_info->param_id;
|
|
|
+ ptr_info_v2->param_size = temp_ptr_info->param_size;
|
|
|
+ ptr_info_v2->param_data = temp_ptr_info->param_data;
|
|
|
+ ptr_info_v2->param_type = temp_ptr_info->param_type;
|
|
|
|
|
|
- info_v2.instance_id = INSTANCE_ID_0;
|
|
|
- info_v2.stage_idx = LSM_STAGE_INDEX_FIRST;
|
|
|
+ ptr_info_v2->instance_id = INSTANCE_ID_0;
|
|
|
+ ptr_info_v2->stage_idx = LSM_STAGE_INDEX_FIRST;
|
|
|
+ ptr_info_v2->model_id = 0;
|
|
|
|
|
|
- ptr_info_v2 = &info_v2;
|
|
|
temp_ptr_info++;
|
|
|
} else {
|
|
|
- /* Just copy the pointer as user already provided v2 params */
|
|
|
+ if (LSM_REG_MULTI_SND_MODEL != temp_ptr_info_v2->param_type ||
|
|
|
+ LSM_DEREG_MULTI_SND_MODEL !=
|
|
|
+ temp_ptr_info_v2->param_type ||
|
|
|
+ LSM_MULTI_SND_MODEL_CONFIDENCE_LEVELS !=
|
|
|
+ temp_ptr_info_v2->param_type) {
|
|
|
+ /* set sound model id to 0 for backward compatibility */
|
|
|
+ temp_ptr_info_v2->model_id = 0;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * Just copy the pointer as user
|
|
|
+ * already provided sound model id
|
|
|
+ */
|
|
|
ptr_info_v2 = temp_ptr_info_v2;
|
|
|
temp_ptr_info_v2++;
|
|
|
}
|
|
|
err = msm_lsm_process_params(substream, ptr_info_v2);
|
|
|
if (err)
|
|
|
dev_err(rtd->dev,
|
|
|
- "%s: Failed to process param, type%d stage=%d err=%d\n",
|
|
|
+ "%s: Failed to process param, type=%d stage=%d err=%d\n",
|
|
|
__func__, ptr_info_v2->param_type,
|
|
|
ptr_info_v2->stage_idx, err);
|
|
|
}
|
|
@@ -2464,7 +2670,7 @@ static int msm_lsm_open(struct snd_pcm_substream *substream)
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
struct lsm_priv *prtd;
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
- int ret = 0;
|
|
|
+ int ret = 0, i;
|
|
|
|
|
|
pr_debug("%s\n", __func__);
|
|
|
prtd = kzalloc(sizeof(struct lsm_priv), GFP_KERNEL);
|
|
@@ -2530,6 +2736,12 @@ static int msm_lsm_open(struct snd_pcm_substream *substream)
|
|
|
prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY;
|
|
|
prtd->lsm_client->fe_id = rtd->dai_link->id;
|
|
|
prtd->lsm_client->unprocessed_data = 0;
|
|
|
+ prtd->lsm_client->num_sound_models = 0;
|
|
|
+ prtd->lsm_client->num_keywords = 0;
|
|
|
+ prtd->lsm_client->multi_snd_model_confidence_levels = NULL;
|
|
|
+
|
|
|
+ for (i = 0; i < LSM_MAX_STAGES_PER_SESSION; i++)
|
|
|
+ INIT_LIST_HEAD(&prtd->lsm_client->stage_cfg[i].sound_models);
|
|
|
|
|
|
prtd->ws = wakeup_source_register(rtd->dev, "lsm-client");
|
|
|
|