mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
Merge a0065850fd on remote branch
Change-Id: If825a98e253033a4e8c415b3a5db33ead20ca353
This commit is contained in:
commit
fc37f37a63
16 changed files with 4082 additions and 3783 deletions
|
|
@ -1194,17 +1194,7 @@ static int wsa881x_probe(struct snd_soc_component *component)
|
|||
"client failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
mutex_init(&wsa_pdata[wsa881x_index].bg_lock);
|
||||
mutex_init(&wsa_pdata[wsa881x_index].res_lock);
|
||||
snprintf(wsa_pdata[wsa881x_index].tz_pdata.name, 100, "%s",
|
||||
wsa_tz_names[wsa881x_index]);
|
||||
wsa_pdata[wsa881x_index].component = component;
|
||||
wsa_pdata[wsa881x_index].spk_pa_gain = SPK_GAIN_12DB;
|
||||
wsa_pdata[wsa881x_index].component = component;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.component = component;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read =
|
||||
wsa881x_temp_reg_read;
|
||||
snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]);
|
||||
|
||||
while (retry) {
|
||||
if (wsa_pdata[wsa881x_index].regmap_flag)
|
||||
break;
|
||||
|
|
@ -1216,6 +1206,18 @@ static int wsa881x_probe(struct snd_soc_component *component)
|
|||
"analog slave not initilized\n", __func__);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
mutex_init(&wsa_pdata[wsa881x_index].bg_lock);
|
||||
mutex_init(&wsa_pdata[wsa881x_index].res_lock);
|
||||
snprintf(wsa_pdata[wsa881x_index].tz_pdata.name, 100, "%s",
|
||||
wsa_tz_names[wsa881x_index]);
|
||||
wsa_pdata[wsa881x_index].component = component;
|
||||
wsa_pdata[wsa881x_index].spk_pa_gain = SPK_GAIN_12DB;
|
||||
wsa_pdata[wsa881x_index].component = component;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.component = component;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read =
|
||||
wsa881x_temp_reg_read;
|
||||
snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]);
|
||||
wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata);
|
||||
INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work,
|
||||
wsa881x_ocp_ctl_work);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
|
||||
|
|
@ -29,6 +30,9 @@
|
|||
#include <sound/info.h>
|
||||
#include <dsp/audio_notifier.h>
|
||||
#include "msm_dailink.h"
|
||||
#include <soc/qcom/subsystem_restart.h>
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
#include <soc/qcom/boot_stats.h>
|
||||
|
||||
|
||||
#define DRV_NAME "spf-asoc-snd"
|
||||
|
|
@ -823,6 +827,31 @@ void msm_common_set_pdata(struct snd_soc_card *card,
|
|||
pdata->common_pdata = common_pdata;
|
||||
}
|
||||
|
||||
static int auto_spf_dummy_ssr_cb(struct notifier_block *this,
|
||||
unsigned long code,
|
||||
void *data)
|
||||
{
|
||||
struct snd_soc_card *card = platform_get_drvdata(spdev);
|
||||
|
||||
switch (code) {
|
||||
case SUBSYS_BEFORE_SHUTDOWN:
|
||||
snd_soc_card_change_online_state(card, 0); // change sndcard status to OFFLINE
|
||||
dev_info(&spdev->dev, "ssr restart, mark sndcard offline\n");
|
||||
break;
|
||||
case SUBSYS_AFTER_POWERUP:
|
||||
snd_soc_card_change_online_state(card, 1); // change sndcard status to ONLINE
|
||||
dev_info(&spdev->dev, "ssr complete, mark sndcard online\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block auto_spf_dummy_ssr_notifier = {
|
||||
.notifier_call = auto_spf_dummy_ssr_cb,
|
||||
};
|
||||
|
||||
static int msm_asoc_machine_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card;
|
||||
|
|
@ -881,8 +910,13 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||
}
|
||||
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
|
||||
pr_err("Sound card %s registered\n", card->name);
|
||||
place_marker("M - sound card init complete");
|
||||
|
||||
spdev = pdev;
|
||||
|
||||
subsys_notif_register_notifier("adsp", &auto_spf_dummy_ssr_notifier);
|
||||
dev_info(&pdev->dev, "Audio driver register for SSR complete\n");
|
||||
|
||||
return 0;
|
||||
err:
|
||||
devm_kfree(&pdev->dev, pdata);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _KONA_PORT_CONFIG
|
||||
|
|
@ -15,56 +16,56 @@
|
|||
*/
|
||||
|
||||
static struct port_params wsa_frame_params_default[SWR_MSTR_PORT_LEN] = {
|
||||
{7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{63, 12, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF},
|
||||
{7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{63, 13, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF},
|
||||
{15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0x00, 0x00},
|
||||
{31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0x00, 0x00},
|
||||
{63, 12, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF , 0x00, 0x00},
|
||||
{7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0x00, 0x00},
|
||||
{31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0x00, 0x00},
|
||||
{63, 13, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF , 0x00, 0x00},
|
||||
{15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0x00, 0x00},
|
||||
{15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF , 0x00, 0x00},
|
||||
};
|
||||
|
||||
static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
|
||||
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
|
||||
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
|
||||
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0},
|
||||
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
|
||||
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0},
|
||||
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00},
|
||||
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00},
|
||||
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00},
|
||||
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00},
|
||||
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00},
|
||||
};
|
||||
|
||||
static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
|
||||
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
|
||||
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
|
||||
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0},
|
||||
{7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0},
|
||||
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0},
|
||||
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00},
|
||||
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00},
|
||||
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00},
|
||||
{7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0, 0x00, 0x00},
|
||||
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0, 0x00, 0x00},
|
||||
};
|
||||
|
||||
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
|
||||
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},/* PCM OUT */
|
||||
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX1 */
|
||||
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX2 */
|
||||
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */
|
||||
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX4 */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},/* PCM OUT */
|
||||
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
|
||||
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
|
||||
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
|
||||
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX4 */
|
||||
};
|
||||
|
||||
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
|
||||
static struct port_params tx_frame_params_v2[SWR_MSTR_PORT_LEN] = {
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},/* PCM OUT */
|
||||
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX1 */
|
||||
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX2 */
|
||||
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */
|
||||
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX4 */
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},/* PCM OUT */
|
||||
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
|
||||
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 0x00, 0x00}, /* TX2 */
|
||||
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
|
||||
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 0x00, 0x00}, /* TX4 */
|
||||
};
|
||||
|
||||
static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = {
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
|
||||
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
|
||||
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
|
||||
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
|
||||
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
|
||||
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00},
|
||||
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00},
|
||||
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00},
|
||||
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00},
|
||||
};
|
||||
|
||||
static struct swr_mstr_port_map sm_port_map[] = {
|
||||
|
|
|
|||
190
asoc/kona.c
190
asoc/kona.c
|
|
@ -897,6 +897,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text);
|
|||
static SOC_ENUM_SINGLE_EXT_DECL(afe_loopback_tx_chs, afe_loopback_tx_ch_text);
|
||||
|
||||
static bool is_initial_boot;
|
||||
static bool is_wsa8810;
|
||||
static bool codec_reg_done;
|
||||
static struct snd_soc_aux_dev *msm_aux_dev;
|
||||
static struct snd_soc_codec_conf *msm_codec_conf;
|
||||
|
|
@ -5548,43 +5549,66 @@ static int msm_int_wsa_init(struct snd_soc_pcm_runtime *rtd)
|
|||
unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
|
||||
struct snd_soc_component *component = NULL;
|
||||
struct snd_soc_dapm_context *dapm = NULL;
|
||||
struct snd_card *card = NULL;
|
||||
struct snd_info_entry *entry;
|
||||
struct msm_asoc_mach_data *pdata =
|
||||
snd_soc_card_get_drvdata(rtd->card);
|
||||
int wsa_active_devs = 0;
|
||||
|
||||
card = rtd->card->snd_card;
|
||||
if (!pdata->codec_root) {
|
||||
entry = msm_snd_info_create_subdir(card->module, "codecs",
|
||||
card->proc_root);
|
||||
if (!entry) {
|
||||
pr_debug("%s: Cannot create codecs module entry\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
pdata->codec_root = entry;
|
||||
}
|
||||
|
||||
if (pdata->wsa_max_devs > 0) {
|
||||
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1");
|
||||
if (!component)
|
||||
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.3");
|
||||
if (component) {
|
||||
dapm = snd_soc_component_get_dapm(component);
|
||||
|
||||
wsa881x_set_channel_map(component, &spkleft_ports[0],
|
||||
WSA883X_MAX_SWR_PORTS, &ch_mask[0],
|
||||
&ch_rate[0], &spkleft_port_types[0]);
|
||||
if (strnstr(component->name, "wsa883x", sizeof(component->name))) {
|
||||
wsa883x_set_channel_map(component, &spkleft_ports[0],
|
||||
WSA883X_MAX_SWR_PORTS, &ch_mask[0],
|
||||
&ch_rate[0], &spkleft_port_types[0]);
|
||||
wsa883x_codec_info_create_codec_entry(pdata->codec_root,
|
||||
component);
|
||||
} else if (strnstr(component->name, "wsa881x", sizeof(component->name))) {
|
||||
wsa881x_set_channel_map(component, &spkleft_ports[0],
|
||||
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
|
||||
&ch_rate[0], &spkleft_port_types[0]);
|
||||
wsa881x_codec_info_create_codec_entry(pdata->codec_root,
|
||||
component);
|
||||
}
|
||||
|
||||
if (dapm->component) {
|
||||
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
|
||||
}
|
||||
/*
|
||||
* Send speaker configuration only for WSA8810.
|
||||
* Default configuration is for WSA8815.
|
||||
*/
|
||||
wsa_macro_set_spkr_mode(component,WSA_MACRO_SPKR_MODE_1);
|
||||
wsa_macro_set_spkr_gain_offset(component,WSA_MACRO_GAIN_OFFSET_M1P5_DB);
|
||||
wsa881x_codec_info_create_codec_entry(pdata->codec_root,
|
||||
component);
|
||||
|
||||
if (!strcmp(component->name, WSA8810_NAME_1) ||
|
||||
!strcmp(component->name, WSA8810_NAME_2))
|
||||
is_wsa8810 = true;
|
||||
|
||||
wsa_active_devs++;
|
||||
} else {
|
||||
pr_info("%s: wsa-codec.1 component is NULL\n", __func__);
|
||||
pr_err("%s: wsa-codec.1 and wsa-codec.3 component are NULL\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
/* If current platform has more than one WSA */
|
||||
if (pdata->wsa_max_devs > wsa_active_devs) {
|
||||
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.2");
|
||||
if (!component)
|
||||
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.4");
|
||||
if (!component) {
|
||||
pr_err("%s: wsa-codec.2 component is NULL\n", __func__);
|
||||
pr_err("%s: %d WSA is found. Expect %d WSA.",
|
||||
__func__, wsa_active_devs, pdata->wsa_max_devs);
|
||||
return -EINVAL;
|
||||
|
|
@ -5592,16 +5616,24 @@ static int msm_int_wsa_init(struct snd_soc_pcm_runtime *rtd)
|
|||
|
||||
dapm = snd_soc_component_get_dapm(component);
|
||||
|
||||
wsa881x_set_channel_map(component, &spkright_ports[0],
|
||||
WSA883X_MAX_SWR_PORTS, &ch_mask[0],
|
||||
&ch_rate[0], &spkright_port_types[0]);
|
||||
if (strnstr(component->name, "wsa883x", sizeof(component->name))) {
|
||||
wsa883x_set_channel_map(component, &spkright_ports[0],
|
||||
WSA883X_MAX_SWR_PORTS, &ch_mask[0],
|
||||
&ch_rate[0], &spkright_port_types[0]);
|
||||
wsa883x_codec_info_create_codec_entry(pdata->codec_root,
|
||||
component);
|
||||
} else if (strnstr(component->name, "wsa881x", sizeof(component->name))) {
|
||||
wsa881x_set_channel_map(component, &spkright_ports[0],
|
||||
WSA881X_MAX_SWR_PORTS, &ch_mask[0],
|
||||
&ch_rate[0], &spkright_port_types[0]);
|
||||
wsa881x_codec_info_create_codec_entry(pdata->codec_root,
|
||||
component);
|
||||
}
|
||||
|
||||
if (dapm->component) {
|
||||
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
|
||||
snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
|
||||
}
|
||||
wsa881x_codec_info_create_codec_entry(pdata->codec_root,
|
||||
component);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -5694,22 +5726,27 @@ static int msm_rx_tx_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
* Send speaker configuration only for WSA8810.
|
||||
* Default configuration is for WSA8815.
|
||||
*/
|
||||
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.1");
|
||||
if (!component) {
|
||||
component = snd_soc_rtdcom_lookup(rtd, "wsa-codec.3");
|
||||
if (!component) {
|
||||
pr_debug("%s: wsa-codec.3 component is NULL\n",
|
||||
__func__);
|
||||
} else {
|
||||
wsa_macro_set_spkr_mode(bolero_component,WSA_MACRO_SPKR_MODE_DEFAULT);
|
||||
}
|
||||
} else {
|
||||
wsa_macro_set_spkr_mode(bolero_component,WSA_MACRO_SPKR_MODE_1);
|
||||
wsa_macro_set_spkr_gain_offset(bolero_component,WSA_MACRO_GAIN_OFFSET_M1P5_DB);
|
||||
if (is_wsa8810) {
|
||||
wsa_macro_set_spkr_mode(bolero_component,
|
||||
WSA_MACRO_SPKR_MODE_1);
|
||||
wsa_macro_set_spkr_gain_offset(bolero_component,
|
||||
WSA_MACRO_GAIN_OFFSET_M1P5_DB);
|
||||
}
|
||||
|
||||
if (pdata->wcd_disabled) {
|
||||
codec_reg_done = true;
|
||||
if (pdata->lito_v2_enabled) {
|
||||
/*
|
||||
* Enable tx data line3 for saipan version v2 and
|
||||
* write corresponding lpi register.
|
||||
*/
|
||||
bolero_set_port_map(bolero_component, ARRAY_SIZE(sm_port_map_v2),
|
||||
|
||||
sm_port_map_v2);
|
||||
} else {
|
||||
bolero_set_port_map(bolero_component, ARRAY_SIZE(sm_port_map),
|
||||
sm_port_map);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -5759,10 +5796,10 @@ static int msm_rx_tx_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
* Enable tx data line3 for saipan version v2 and
|
||||
* write corresponding lpi register.
|
||||
*/
|
||||
bolero_set_port_map(component, ARRAY_SIZE(sm_port_map_v2),
|
||||
bolero_set_port_map(bolero_component, ARRAY_SIZE(sm_port_map_v2),
|
||||
sm_port_map_v2);
|
||||
} else {
|
||||
bolero_set_port_map(component, ARRAY_SIZE(sm_port_map),
|
||||
bolero_set_port_map(bolero_component, ARRAY_SIZE(sm_port_map),
|
||||
sm_port_map);
|
||||
}
|
||||
}
|
||||
|
|
@ -7162,10 +7199,12 @@ static struct snd_soc_dai_link msm_kona_dai_links[
|
|||
static int msm_populate_dai_link_component_of_node(
|
||||
struct snd_soc_card *card)
|
||||
{
|
||||
int i, index, ret = 0;
|
||||
int i, j, index, ret = 0;
|
||||
struct device *cdev = card->dev;
|
||||
struct snd_soc_dai_link *dai_link = card->dai_link;
|
||||
struct device_node *np;
|
||||
int codecs_enabled = 0;
|
||||
struct snd_soc_dai_link_component *codecs_comp = NULL;
|
||||
|
||||
if (!cdev) {
|
||||
dev_err(cdev, "%s: Sound card device memory NULL\n", __func__);
|
||||
|
|
@ -7222,22 +7261,77 @@ static int msm_populate_dai_link_component_of_node(
|
|||
}
|
||||
|
||||
/* populate codec_of_node for snd card dai links */
|
||||
if (dai_link[i].codecs->name && !dai_link[i].codecs->of_node) {
|
||||
index = of_property_match_string(cdev->of_node,
|
||||
"asoc-codec-names",
|
||||
dai_link[i].codecs->name);
|
||||
if (index < 0)
|
||||
continue;
|
||||
np = of_parse_phandle(cdev->of_node, "asoc-codec",
|
||||
index);
|
||||
if (!np) {
|
||||
dev_err(cdev, "%s: retrieving phandle for codec %s failed\n",
|
||||
__func__, dai_link[i].codecs->name);
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
if (dai_link[i].num_codecs > 0) {
|
||||
for (j = 0; j < dai_link[i].num_codecs; j++) {
|
||||
if (dai_link[i].codecs[j].of_node ||
|
||||
!dai_link[i].codecs[j].name)
|
||||
continue;
|
||||
|
||||
index = of_property_match_string(cdev->of_node,
|
||||
"asoc-codec-names",
|
||||
dai_link[i].codecs[j].name);
|
||||
if (index < 0)
|
||||
continue;
|
||||
np = of_parse_phandle(cdev->of_node,
|
||||
"asoc-codec",
|
||||
index);
|
||||
if (!np) {
|
||||
dev_err(cdev, "%s: retrieving phandle for codec %s failed\n",
|
||||
__func__,
|
||||
dai_link[i].codecs[j].name);
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
dai_link[i].codecs[j].of_node = np;
|
||||
dai_link[i].codecs[j].name = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In multi-codec scenario, check if codecs are enabled for this platform */
|
||||
for (i = 0; i < card->num_links; i++) {
|
||||
codecs_enabled = 0;
|
||||
if (dai_link[i].num_codecs > 1) {
|
||||
for (j = 0; j < dai_link[i].num_codecs; j++) {
|
||||
if (!dai_link[i].codecs[j].of_node)
|
||||
continue;
|
||||
|
||||
np = dai_link[i].codecs[j].of_node;
|
||||
if (!of_device_is_available(np)) {
|
||||
dev_dbg(cdev, "%s: codec is disabled: %s\n",
|
||||
__func__,
|
||||
np->full_name);
|
||||
dai_link[i].codecs[j].of_node = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
codecs_enabled++;
|
||||
}
|
||||
if (codecs_enabled > 0 &&
|
||||
codecs_enabled < dai_link[i].num_codecs) {
|
||||
codecs_comp = devm_kzalloc(cdev,
|
||||
sizeof(struct snd_soc_dai_link_component)
|
||||
* codecs_enabled, GFP_KERNEL);
|
||||
if (!codecs_comp) {
|
||||
dev_err(cdev, "%s: %s dailink codec component alloc failed\n",
|
||||
__func__, dai_link[i].name);
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
index = 0;
|
||||
for (j = 0; j < dai_link[i].num_codecs; j++) {
|
||||
if(dai_link[i].codecs[j].of_node) {
|
||||
codecs_comp[index].of_node =
|
||||
dai_link[i].codecs[j].of_node;
|
||||
codecs_comp[index].dai_name =
|
||||
dai_link[i].codecs[j].dai_name;
|
||||
codecs_comp[index].name = NULL;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
dai_link[i].codecs = codecs_comp;
|
||||
dai_link[i].num_codecs = codecs_enabled;
|
||||
}
|
||||
dai_link[i].codecs->of_node = np;
|
||||
dai_link[i].codecs->name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
25
asoc/msm-dai-q6-v2.c
Executable file → Normal file
25
asoc/msm-dai-q6-v2.c
Executable file → Normal file
|
|
@ -494,6 +494,9 @@ static struct afe_param_id_tdm_lane_cfg tdm_lane_cfg = {
|
|||
0x0,
|
||||
};
|
||||
|
||||
#define LIMITER_PARM_MAX 3
|
||||
static u16 limiter_param[LIMITER_PARM_MAX];
|
||||
|
||||
/* cache of group cfg per parent node */
|
||||
static struct afe_param_id_group_device_tdm_cfg tdm_group_cfg = {
|
||||
AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG,
|
||||
|
|
@ -10579,7 +10582,7 @@ static int msm_pcm_afe_limiter_param_ctl_info(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
ucontrol->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
/* two int values: port_id and enable/disable */
|
||||
ucontrol->count = 2;
|
||||
ucontrol->count = LIMITER_PARM_MAX;
|
||||
/* Valid range is all positive values to support above controls */
|
||||
ucontrol->value.integer.min = 0;
|
||||
ucontrol->value.integer.max = INT_MAX;
|
||||
|
|
@ -10589,6 +10592,9 @@ static int msm_pcm_afe_limiter_param_ctl_info(struct snd_kcontrol *kcontrol,
|
|||
static int msm_pcm_afe_limiter_param_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.integer.value[0] = limiter_param[0];
|
||||
ucontrol->value.integer.value[1] = limiter_param[1];
|
||||
ucontrol->value.integer.value[2] = limiter_param[2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -10600,17 +10606,30 @@ static int msm_pcm_afe_limiter_param_ctl_put(struct snd_kcontrol *kcontrol,
|
|||
struct param_hdr_v3 param_hdr;
|
||||
int ret = -EINVAL;
|
||||
|
||||
limiter_param[0] = ucontrol->value.integer.value[0];
|
||||
limiter_param[1] = ucontrol->value.integer.value[1];
|
||||
limiter_param[2] = ucontrol->value.integer.value[2];
|
||||
|
||||
|
||||
if(limiter_param[2] != LIMITER_PARM_MAX - 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_debug("%s: enter\n", __func__);
|
||||
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||||
|
||||
port_id = ucontrol->value.integer.value[0];
|
||||
afe_limiter_disable.disable_afe_limiter = ucontrol->value.integer.value[1];
|
||||
port_id = limiter_param[0];
|
||||
afe_limiter_disable.disable_afe_limiter = limiter_param[1];
|
||||
|
||||
ret = afe_port_send_afe_limiter_param(port_id, &afe_limiter_disable);
|
||||
if (ret)
|
||||
pr_err("%s: AFE port logging setting for port 0x%x failed %d\n",
|
||||
__func__, port_id, ret);
|
||||
|
||||
//resetting number of parameters to zero
|
||||
limiter_param[2] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2062,8 +2062,7 @@ static int msm_loopback_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
|
|||
audio_client = q6asm_get_audio_client(fe_dai.strm_id);
|
||||
|
||||
event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data;
|
||||
if ((event_data->event_type < ADSP_STREAM_PP_EVENT) ||
|
||||
(event_data->event_type >= ADSP_STREAM_EVENT_MAX)) {
|
||||
if (event_data->event_type >= ADSP_STREAM_EVENT_MAX) {
|
||||
pr_err("%s: invalid event_type=%d\n",
|
||||
__func__, event_data->event_type);
|
||||
ret = -EINVAL;
|
||||
|
|
|
|||
2917
asoc/msm-pcm-routing-auto.c
Executable file → Normal file
2917
asoc/msm-pcm-routing-auto.c
Executable file → Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -3052,6 +3052,11 @@ static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
|
|||
pr_debug("%s: FE DAI 0x%x session_id 0x%x\n",
|
||||
__func__, val, session_id);
|
||||
|
||||
if (!session_id) {
|
||||
pr_err("%s: Invalid session_id %x\n", __func__, session_id);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&routing_lock);
|
||||
|
||||
if (set)
|
||||
|
|
|
|||
|
|
@ -1039,21 +1039,27 @@ SND_SOC_DAILINK_DEFS(wsa_dma_rx0,
|
|||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45056")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "wsa_macro_rx1"),
|
||||
COMP_CODEC("wsa-codec1", "wsa_rx1"),
|
||||
COMP_CODEC("wsa-codec2", "wsa_rx2")),
|
||||
COMP_CODEC("wsa-codec2", "wsa_rx2"),
|
||||
COMP_CODEC("wsa-codec3", "wsa_rx3"),
|
||||
COMP_CODEC("wsa-codec4", "wsa_rx4")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(wsa_dma_rx1,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45058")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "wsa_macro_rx_mix"),
|
||||
COMP_CODEC("wsa-codec1", "wsa_rx1"),
|
||||
COMP_CODEC("wsa-codec2", "wsa_rx2")),
|
||||
COMP_CODEC("wsa-codec2", "wsa_rx2"),
|
||||
COMP_CODEC("wsa-codec3", "wsa_rx3"),
|
||||
COMP_CODEC("wsa-codec4", "wsa_rx4")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(wsa_dma_tx1,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-cdc-dma-dev.45059")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("bolero_codec", "wsa_macro_echo"),
|
||||
COMP_CODEC("wsa-codec1", "wsa_rx1"),
|
||||
COMP_CODEC("wsa-codec2", "wsa_rx2")),
|
||||
COMP_CODEC("wsa-codec2", "wsa_rx2"),
|
||||
COMP_CODEC("wsa-codec3", "wsa_rx3"),
|
||||
COMP_CODEC("wsa-codec4", "wsa_rx4")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(rx_dma_rx0,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,8 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
# Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
|
||||
ifeq ($(CONFIG_QGKI), y)
|
||||
export CONFIG_SND_SOC_GVM_AUTO_SPF=m
|
||||
export CONFIG_MSM_QDSP6_APRV2_VM=m
|
||||
export CONFIG_MSM_QDSP6_SSR=m
|
||||
export CONFIG_MSM_ADSP_LOADER=m
|
||||
export CONFIG_MSM_QDSP6_NOTIFIER=m
|
||||
export CONFIG_SND_SOC_MSM_QDSP6V2_VM=m
|
||||
export CONFIG_SND_SOC_QDSP6V2=m
|
||||
export CONFIG_QTI_PP=m
|
||||
export CONFIG_SND_HWDEP_ROUTING=m
|
||||
export CONFIG_SND_SOC_MSM_STUB=m
|
||||
export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
|
||||
export CONFIG_MSM_QDSP6V2_CODECS=m
|
||||
export CONFIG_SND_EVENT=m
|
||||
export CONFIG_SND_SOC_SA8155=m
|
||||
endif
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright (c) 2018-2019, 2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. 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
|
||||
|
|
@ -11,17 +12,5 @@
|
|||
*/
|
||||
|
||||
#define CONFIG_SND_SOC_GVM_AUTO_SPF 1
|
||||
#define CONFIG_MSM_QDSP6_APRV2_VM 1
|
||||
#define CONFIG_MSM_ADSP_LOADER 1
|
||||
#define CONFIG_MSM_QDSP6_SSR 1
|
||||
#define CONFIG_MSM_QDSP6_NOTIFIER 1
|
||||
#define CONFIG_SND_SOC_MSM_QDSP6V2_VM 1
|
||||
#define CONFIG_SND_SOC_QDSP6V2 1
|
||||
#define CONFIG_QTI_PP 1
|
||||
#define CONFIG_SND_HWDEP_ROUTING 1
|
||||
#define CONFIG_SND_SOC_MSM_STUB 1
|
||||
#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1
|
||||
#define CONFIG_MSM_QDSP6V2_CODECS 1
|
||||
#define CONFIG_SND_EVENT 1
|
||||
#define CONFIG_SND_SOC_SA8155 1
|
||||
|
||||
|
|
|
|||
|
|
@ -47,3 +47,4 @@ export CONFIG_SND_SOC_WCD937X=m
|
|||
export CONFIG_SND_SOC_WCD937X_SLAVE=m
|
||||
export CONFIG_SND_EVENT=m
|
||||
export CONFIG_HSIF_DISABLE=m
|
||||
export CONFIG_DIGITAL_CDC_RSC_MGR=m
|
||||
|
|
|
|||
|
|
@ -52,3 +52,4 @@
|
|||
#define CONFIG_SND_SOC_WCD937X_SLAVE 1
|
||||
#define CONFIG_SND_EVENT 1
|
||||
#define CONFIG_HSIF_DISABLE 1
|
||||
#define CONFIG_DIGITAL_CDC_RSC_MGR 1
|
||||
|
|
|
|||
53
dsp/q6afe.c
Executable file → Normal file
53
dsp/q6afe.c
Executable file → Normal file
|
|
@ -2144,31 +2144,30 @@ static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block)
|
|||
result = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (cal_block->cal_data.size < 0) {
|
||||
pr_debug("%s: AFE cal has invalid size!\n", __func__);
|
||||
result = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (cal_block->cal_data.size == 0) {
|
||||
pr_debug("%s: AFE cal size is zero!\n", __func__);
|
||||
goto done;
|
||||
}
|
||||
payload_size = cal_block->cal_data.size;
|
||||
mem_hdr.data_payload_addr_lsw =
|
||||
lower_32_bits(cal_block->cal_data.paddr);
|
||||
mem_hdr.data_payload_addr_msw =
|
||||
msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
|
||||
mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle;
|
||||
if (cal_block->cal_data.size != 0) {
|
||||
payload_size = cal_block->cal_data.size;
|
||||
mem_hdr.data_payload_addr_lsw =
|
||||
lower_32_bits(cal_block->cal_data.paddr);
|
||||
mem_hdr.data_payload_addr_msw =
|
||||
msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
|
||||
mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle;
|
||||
|
||||
pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
|
||||
__func__, port_id,
|
||||
cal_block->cal_data.size, &cal_block->cal_data.paddr);
|
||||
pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
|
||||
__func__, port_id,
|
||||
cal_block->cal_data.size, &cal_block->cal_data.paddr);
|
||||
|
||||
result = q6afe_set_params(port_id, q6audio_get_port_index(port_id),
|
||||
result = q6afe_set_params(port_id, q6audio_get_port_index(port_id),
|
||||
&mem_hdr, NULL, payload_size);
|
||||
if (result)
|
||||
pr_err("%s: AFE cal for port 0x%x failed %d\n",
|
||||
__func__, port_id, result);
|
||||
if (result)
|
||||
pr_err("%s: AFE cal for port 0x%x failed %d\n",
|
||||
__func__, port_id, result);
|
||||
}
|
||||
else {
|
||||
pr_debug("%s: AFE cal has invalid size!\n", __func__);
|
||||
result = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
return result;
|
||||
|
|
@ -2982,7 +2981,7 @@ int afe_send_cdc_dma_data_align(u16 port_id, u32 cdc_dma_data_align)
|
|||
{
|
||||
struct afe_param_id_cdc_dma_data_align data_align;
|
||||
struct param_hdr_v3 param_info;
|
||||
uint16_t port_index = 0;
|
||||
int port_index = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
memset(&data_align, 0, sizeof(data_align));
|
||||
|
|
@ -3174,7 +3173,7 @@ static int afe_port_topology_deregister(u16 port_id)
|
|||
uint32_t build_major_version = 0;
|
||||
uint32_t build_minor_version = 0;
|
||||
uint32_t build_branch_version = 0;
|
||||
uint32_t afe_api_version = 0;
|
||||
int afe_api_version = 0;
|
||||
|
||||
ret = q6core_get_avcs_avs_build_version_info(&build_major_version,
|
||||
&build_minor_version,
|
||||
|
|
@ -4791,7 +4790,7 @@ EXPORT_SYMBOL(afe_set_island_mode_cfg);
|
|||
*/
|
||||
int afe_get_power_mode_cfg(u16 port_id, u32 *enable_flag)
|
||||
{
|
||||
uint16_t port_index;
|
||||
int port_index;
|
||||
int ret = 0;
|
||||
|
||||
if (enable_flag) {
|
||||
|
|
@ -4815,7 +4814,7 @@ EXPORT_SYMBOL(afe_get_power_mode_cfg);
|
|||
*/
|
||||
int afe_set_power_mode_cfg(u16 port_id, u32 enable_flag)
|
||||
{
|
||||
uint16_t port_index;
|
||||
int port_index;
|
||||
int ret= 0;
|
||||
|
||||
port_index = afe_get_port_index(port_id);
|
||||
|
|
@ -10010,7 +10009,7 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg)
|
|||
{
|
||||
int index = 0;
|
||||
int ret = 0;
|
||||
u16 idx = 0;
|
||||
int idx = 0;
|
||||
uint32_t build_major_version = 0;
|
||||
uint32_t build_minor_version = 0;
|
||||
uint32_t build_branch_version = 0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
|
|
@ -265,12 +266,14 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
|
|||
|
||||
pad = pctldev->desc->pins[pin].drv_data;
|
||||
|
||||
pad->function = function;
|
||||
if (pad != NULL) {
|
||||
pad->function = function;
|
||||
|
||||
val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL);
|
||||
val &= ~(LPI_GPIO_REG_FUNCTION_MASK);
|
||||
val |= pad->function << LPI_GPIO_REG_FUNCTION_SHIFT;
|
||||
lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val);
|
||||
val = lpi_gpio_read(pad, LPI_GPIO_REG_VAL_CTL);
|
||||
val &= ~(LPI_GPIO_REG_FUNCTION_MASK);
|
||||
val |= pad->function << LPI_GPIO_REG_FUNCTION_SHIFT;
|
||||
lpi_gpio_write(pad, LPI_GPIO_REG_VAL_CTL, val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,6 +304,8 @@ void snd_event_mstr_add_client(struct snd_event_clients **snd_clients,
|
|||
GFP_KERNEL);
|
||||
if (!client->cl_arr) {
|
||||
*snd_clients = ERR_PTR(-ENOMEM);
|
||||
kfree(client);
|
||||
client = NULL;
|
||||
return;
|
||||
}
|
||||
*snd_clients = client;
|
||||
|
|
|
|||
Loading…
Reference in a new issue