From patchwork Mon Feb 24 01:13:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Wang X-Patchwork-Id: 1242780 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48Qkbc3GLGz9sSH; Mon, 24 Feb 2020 12:13:48 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1j62Jb-0005v8-UN; Mon, 24 Feb 2020 01:13:43 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62JW-0005tN-5p for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:38 +0000 Received: from [123.112.111.131] (helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62JV-0000vQ-By for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:37 +0000 From: Hui Wang To: kernel-team@lists.ubuntu.com Subject: [SRU][Focal][PATCH 1/4] ASoC: SOF: enable dual control for pga Date: Mon, 24 Feb 2020 09:13:08 +0800 Message-Id: <20200224011311.7178-2-hui.wang@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200224011311.7178-1-hui.wang@canonical.com> References: <20200224011311.7178-1-hui.wang@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jaska Uimonen BugLink: https://bugs.launchpad.net/bugs/1864398 Currently sof pga element supports only 1 kcontrol and you can't create for example a mixer element with combined volume slider and mute switch. So enable sof pga to have more than 1 kcontrol associated with it. Also check for possible NULL tlv pointer as switch element might not have it. Signed-off-by: Jaska Uimonen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191008164443.1358-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown (cherry picked from commit a68c6b6cc77b841dc37c17a5d9a7074e26801af5) Signed-off-by: Hui Wang --- sound/soc/sof/topology.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index fa299e078156..96c20c889fa4 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1581,7 +1581,7 @@ static int sof_widget_load_pga(struct snd_soc_component *scomp, int index, if (!volume) return -ENOMEM; - if (le32_to_cpu(tw->num_kcontrols) != 1) { + if (!le32_to_cpu(tw->num_kcontrols)) { dev_err(sdev->dev, "error: invalid kcontrol count %d for volume\n", tw->num_kcontrols); ret = -EINVAL; @@ -1618,7 +1618,8 @@ static int sof_widget_load_pga(struct snd_soc_component *scomp, int index, swidget->private = volume; list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { - if (scontrol->comp_id == swidget->comp_id) { + if (scontrol->comp_id == swidget->comp_id && + scontrol->volume_table) { min_step = scontrol->min_volume_step; max_step = scontrol->max_volume_step; volume->min_value = scontrol->volume_table[min_step]; From patchwork Mon Feb 24 01:13:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Wang X-Patchwork-Id: 1242778 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48QkbY6Ll0z9sRk; Mon, 24 Feb 2020 12:13:45 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1j62JZ-0005ts-HA; Mon, 24 Feb 2020 01:13:41 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62JX-0005tc-OF for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:39 +0000 Received: from [123.112.111.131] (helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62JW-0000vQ-U2 for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:39 +0000 From: Hui Wang To: kernel-team@lists.ubuntu.com Subject: [SRU][Focal][PATCH 2/4] AsoC: SOF: refactor control load code Date: Mon, 24 Feb 2020 09:13:09 +0800 Message-Id: <20200224011311.7178-3-hui.wang@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200224011311.7178-1-hui.wang@canonical.com> References: <20200224011311.7178-1-hui.wang@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jaska Uimonen BugLink: https://bugs.launchpad.net/bugs/1864398 Move code around to enable token parsing in control load. Signed-off-by: Jaska Uimonen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191008164443.1358-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown (backported from commit acf1b71cb693263c7c9373296e872a8fa61a5cf3) Signed-off-by: Hui Wang --- sound/soc/sof/topology.c | 315 +++++++++++++++++++-------------------- 1 file changed, 157 insertions(+), 158 deletions(-) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 96c20c889fa4..51db93e0e9cd 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -432,164 +432,6 @@ static enum sof_comp_type find_process_comp_type(enum sof_ipc_process_type type) return SOF_COMP_NONE; } -/* - * Standard Kcontrols. - */ - -static int sof_control_load_volume(struct snd_soc_component *scomp, - struct snd_sof_control *scontrol, - struct snd_kcontrol_new *kc, - struct snd_soc_tplg_ctl_hdr *hdr) -{ - struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); - struct snd_soc_tplg_mixer_control *mc = - container_of(hdr, struct snd_soc_tplg_mixer_control, hdr); - struct sof_ipc_ctrl_data *cdata; - int tlv[TLV_ITEMS]; - unsigned int i; - int ret; - - /* validate topology data */ - if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) - return -EINVAL; - - /* init the volume get/put data */ - scontrol->size = struct_size(scontrol->control_data, chanv, - le32_to_cpu(mc->num_channels)); - scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL); - if (!scontrol->control_data) - return -ENOMEM; - - scontrol->comp_id = sdev->next_comp_id; - scontrol->min_volume_step = le32_to_cpu(mc->min); - scontrol->max_volume_step = le32_to_cpu(mc->max); - scontrol->num_channels = le32_to_cpu(mc->num_channels); - - /* set cmd for mixer control */ - if (le32_to_cpu(mc->max) == 1) { - scontrol->cmd = SOF_CTRL_CMD_SWITCH; - goto out; - } - - scontrol->cmd = SOF_CTRL_CMD_VOLUME; - - /* extract tlv data */ - if (get_tlv_data(kc->tlv.p, tlv) < 0) { - dev_err(sdev->dev, "error: invalid TLV data\n"); - return -EINVAL; - } - - /* set up volume table */ - ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1); - if (ret < 0) { - dev_err(sdev->dev, "error: setting up volume table\n"); - return ret; - } - - /* set default volume values to 0dB in control */ - cdata = scontrol->control_data; - for (i = 0; i < scontrol->num_channels; i++) { - cdata->chanv[i].channel = i; - cdata->chanv[i].value = VOL_ZERO_DB; - } - -out: - dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", - scontrol->comp_id, scontrol->num_channels); - - return 0; -} - -static int sof_control_load_enum(struct snd_soc_component *scomp, - struct snd_sof_control *scontrol, - struct snd_kcontrol_new *kc, - struct snd_soc_tplg_ctl_hdr *hdr) -{ - struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); - struct snd_soc_tplg_enum_control *ec = - container_of(hdr, struct snd_soc_tplg_enum_control, hdr); - - /* validate topology data */ - if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN) - return -EINVAL; - - /* init the enum get/put data */ - scontrol->size = struct_size(scontrol->control_data, chanv, - le32_to_cpu(ec->num_channels)); - scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL); - if (!scontrol->control_data) - return -ENOMEM; - - scontrol->comp_id = sdev->next_comp_id; - scontrol->num_channels = le32_to_cpu(ec->num_channels); - - scontrol->cmd = SOF_CTRL_CMD_ENUM; - - dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n", - scontrol->comp_id, scontrol->num_channels, scontrol->comp_id); - - return 0; -} - -static int sof_control_load_bytes(struct snd_soc_component *scomp, - struct snd_sof_control *scontrol, - struct snd_kcontrol_new *kc, - struct snd_soc_tplg_ctl_hdr *hdr) -{ - struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); - struct sof_ipc_ctrl_data *cdata; - struct snd_soc_tplg_bytes_control *control = - container_of(hdr, struct snd_soc_tplg_bytes_control, hdr); - struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; - int max_size = sbe->max; - - /* init the get/put bytes data */ - scontrol->size = sizeof(struct sof_ipc_ctrl_data) + - le32_to_cpu(control->priv.size); - - if (scontrol->size > max_size) { - dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n", - scontrol->size, max_size); - return -EINVAL; - } - - scontrol->control_data = kzalloc(max_size, GFP_KERNEL); - cdata = scontrol->control_data; - if (!scontrol->control_data) - return -ENOMEM; - - scontrol->comp_id = sdev->next_comp_id; - scontrol->cmd = SOF_CTRL_CMD_BINARY; - - dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", - scontrol->comp_id, scontrol->num_channels); - - if (le32_to_cpu(control->priv.size) > 0) { - memcpy(cdata->data, control->priv.data, - le32_to_cpu(control->priv.size)); - - if (cdata->data->magic != SOF_ABI_MAGIC) { - dev_err(sdev->dev, "error: Wrong ABI magic 0x%08x.\n", - cdata->data->magic); - return -EINVAL; - } - if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, - cdata->data->abi)) { - dev_err(sdev->dev, - "error: Incompatible ABI version 0x%08x.\n", - cdata->data->abi); - return -EINVAL; - } - if (cdata->data->size + sizeof(const struct sof_abi_hdr) != - le32_to_cpu(control->priv.size)) { - dev_err(sdev->dev, - "error: Conflict in bytes vs. priv size.\n"); - return -EINVAL; - } - } - return 0; -} - /* * Topology Token Parsing. * New tokens should be added to headers and parsing tables below. @@ -1040,6 +882,163 @@ static void sof_dbg_comp_config(struct snd_soc_component *scomp, config->frame_fmt); } +/* + * Standard Kcontrols. + */ + +static int sof_control_load_volume(struct snd_soc_component *scomp, + struct snd_sof_control *scontrol, + struct snd_kcontrol_new *kc, + struct snd_soc_tplg_ctl_hdr *hdr) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct snd_soc_tplg_mixer_control *mc = + container_of(hdr, struct snd_soc_tplg_mixer_control, hdr); + struct sof_ipc_ctrl_data *cdata; + int tlv[TLV_ITEMS]; + unsigned int i; + int ret; + + /* validate topology data */ + if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) + return -EINVAL; + + /* init the volume get/put data */ + scontrol->size = struct_size(scontrol->control_data, chanv, + le32_to_cpu(mc->num_channels)); + scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL); + if (!scontrol->control_data) + return -ENOMEM; + + scontrol->comp_id = sdev->next_comp_id; + scontrol->min_volume_step = le32_to_cpu(mc->min); + scontrol->max_volume_step = le32_to_cpu(mc->max); + scontrol->num_channels = le32_to_cpu(mc->num_channels); + + /* set cmd for mixer control */ + if (le32_to_cpu(mc->max) == 1) { + scontrol->cmd = SOF_CTRL_CMD_SWITCH; + goto out; + } + + scontrol->cmd = SOF_CTRL_CMD_VOLUME; + + /* extract tlv data */ + if (get_tlv_data(kc->tlv.p, tlv) < 0) { + dev_err(sdev->dev, "error: invalid TLV data\n"); + return -EINVAL; + } + + /* set up volume table */ + ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1); + if (ret < 0) { + dev_err(sdev->dev, "error: setting up volume table\n"); + return ret; + } + + /* set default volume values to 0dB in control */ + cdata = scontrol->control_data; + for (i = 0; i < scontrol->num_channels; i++) { + cdata->chanv[i].channel = i; + cdata->chanv[i].value = VOL_ZERO_DB; + } + +out: + dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", + scontrol->comp_id, scontrol->num_channels); + + return 0; +} + +static int sof_control_load_enum(struct snd_soc_component *scomp, + struct snd_sof_control *scontrol, + struct snd_kcontrol_new *kc, + struct snd_soc_tplg_ctl_hdr *hdr) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct snd_soc_tplg_enum_control *ec = + container_of(hdr, struct snd_soc_tplg_enum_control, hdr); + + /* validate topology data */ + if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN) + return -EINVAL; + + /* init the enum get/put data */ + scontrol->size = struct_size(scontrol->control_data, chanv, + le32_to_cpu(ec->num_channels)); + scontrol->control_data = kzalloc(scontrol->size, GFP_KERNEL); + if (!scontrol->control_data) + return -ENOMEM; + + scontrol->comp_id = sdev->next_comp_id; + scontrol->num_channels = le32_to_cpu(ec->num_channels); + + scontrol->cmd = SOF_CTRL_CMD_ENUM; + + dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n", + scontrol->comp_id, scontrol->num_channels, scontrol->comp_id); + + return 0; +} + +static int sof_control_load_bytes(struct snd_soc_component *scomp, + struct snd_sof_control *scontrol, + struct snd_kcontrol_new *kc, + struct snd_soc_tplg_ctl_hdr *hdr) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct sof_ipc_ctrl_data *cdata; + struct snd_soc_tplg_bytes_control *control = + container_of(hdr, struct snd_soc_tplg_bytes_control, hdr); + struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; + int max_size = sbe->max; + + if (le32_to_cpu(control->priv.size) > max_size) { + dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n", + control->priv.size, max_size); + return -EINVAL; + } + + /* init the get/put bytes data */ + scontrol->size = sizeof(struct sof_ipc_ctrl_data) + + le32_to_cpu(control->priv.size); + scontrol->control_data = kzalloc(max_size, GFP_KERNEL); + cdata = scontrol->control_data; + if (!scontrol->control_data) + return -ENOMEM; + + scontrol->comp_id = sdev->next_comp_id; + scontrol->cmd = SOF_CTRL_CMD_BINARY; + + dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", + scontrol->comp_id, scontrol->num_channels); + + if (le32_to_cpu(control->priv.size) > 0) { + memcpy(cdata->data, control->priv.data, + le32_to_cpu(control->priv.size)); + + if (cdata->data->magic != SOF_ABI_MAGIC) { + dev_err(sdev->dev, "error: Wrong ABI magic 0x%08x.\n", + cdata->data->magic); + return -EINVAL; + } + if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, + cdata->data->abi)) { + dev_err(sdev->dev, + "error: Incompatible ABI version 0x%08x.\n", + cdata->data->abi); + return -EINVAL; + } + if (cdata->data->size + sizeof(const struct sof_abi_hdr) != + le32_to_cpu(control->priv.size)) { + dev_err(sdev->dev, + "error: Conflict in bytes vs. priv size.\n"); + return -EINVAL; + } + } + return 0; +} + /* external kcontrol init - used for any driver specific init */ static int sof_control_load(struct snd_soc_component *scomp, int index, struct snd_kcontrol_new *kc, From patchwork Mon Feb 24 01:13:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Wang X-Patchwork-Id: 1242779 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48QkbZ415pz9sS3; Mon, 24 Feb 2020 12:13:46 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1j62Ja-0005uT-P6; Mon, 24 Feb 2020 01:13:42 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62JZ-0005tm-AA for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:41 +0000 Received: from [123.112.111.131] (helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62JY-0000vQ-Fv for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:41 +0000 From: Hui Wang To: kernel-team@lists.ubuntu.com Subject: [SRU][Focal][PATCH 3/4] ASoC: SOF: acpi led support for switch controls Date: Mon, 24 Feb 2020 09:13:10 +0800 Message-Id: <20200224011311.7178-4-hui.wang@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200224011311.7178-1-hui.wang@canonical.com> References: <20200224011311.7178-1-hui.wang@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jaska Uimonen BugLink: https://bugs.launchpad.net/bugs/1864398 Currently sof doesn't support acpi leds with mute switches. So implement acpi leds following quite shamelessly existing HDA implementation by Takashi Iwai. Mute leds can be enabled in topology by adding led and direction token in switch control private data. Signed-off-by: Jaska Uimonen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191008164443.1358-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown (cherry picked from commit 5d43001ae43606dc525f55c482c545afba01bb55) Signed-off-by: Hui Wang --- include/uapi/sound/sof/tokens.h | 4 ++++ sound/soc/sof/control.c | 32 ++++++++++++++++++++++++++++++++ sound/soc/sof/sof-priv.h | 9 +++++++++ sound/soc/sof/topology.c | 13 +++++++++++++ 4 files changed, 58 insertions(+) diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index 8f996857fb24..28ef01a67765 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -114,4 +114,8 @@ #define SOF_TKN_IMX_ESAI_FIRST_TOKEN 1100 /* TODO: Add ESAI tokens */ +/* Led control for mute switches */ +#define SOF_TKN_MUTE_LED_USE 1300 +#define SOF_TKN_MUTE_LED_DIRECTION 1301 + #endif diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index 2b8711eda362..b73d4587c5da 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -11,8 +11,37 @@ /* Mixer Controls */ #include +#include #include "sof-priv.h" +static void update_mute_led(struct snd_sof_control *scontrol, + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int temp = 0; + unsigned int mask; + int i; + + mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + for (i = 0; i < scontrol->num_channels; i++) { + if (ucontrol->value.integer.value[i]) { + temp |= mask; + break; + } + } + + if (temp == scontrol->led_ctl.led_value) + return; + + scontrol->led_ctl.led_value = temp; + + if (!scontrol->led_ctl.direction) + ledtrig_audio_set(LED_AUDIO_MUTE, temp ? LED_OFF : LED_ON); + else + ledtrig_audio_set(LED_AUDIO_MICMUTE, temp ? LED_OFF : LED_ON); +} + static inline u32 mixer_to_ipc(unsigned int value, u32 *volume_map, int size) { if (value >= size) @@ -118,6 +147,9 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol, cdata->chanv[i].value = value; } + if (scontrol->led_ctl.use_led) + update_mute_led(scontrol, kcontrol, ucontrol); + /* notify DSP of mixer updates */ if (pm_runtime_active(sdev->dev)) snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol, diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 7b329bd99674..b8c30c0a22e3 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -15,6 +15,7 @@ #include #include +#include #include #include /* needs to be included before control.h */ @@ -305,6 +306,12 @@ struct snd_sof_pcm { bool prepared[2]; /* PCM_PARAMS set successfully */ }; +struct snd_sof_led_control { + unsigned int use_led; + unsigned int direction; + unsigned int led_value; +}; + /* ALSA SOF Kcontrol device */ struct snd_sof_control { struct snd_sof_dev *sdev; @@ -319,6 +326,8 @@ struct snd_sof_control { u32 *volume_table; /* volume table computed from tlv data*/ struct list_head list; /* list in sdev control list */ + + struct snd_sof_led_control led_ctl; }; /* ASoC SOF DAPM widget */ diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 51db93e0e9cd..76e126b533a8 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -682,6 +682,14 @@ static const struct sof_topology_token dmic_pdm_tokens[] = { static const struct sof_topology_token hda_tokens[] = { }; +/* Leds */ +static const struct sof_topology_token led_tokens[] = { + {SOF_TKN_MUTE_LED_USE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct snd_sof_led_control, use_led), 0}, + {SOF_TKN_MUTE_LED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_u32, offsetof(struct snd_sof_led_control, direction), 0}, +}; + static void sof_parse_uuid_tokens(struct snd_soc_component *scomp, void *object, const struct sof_topology_token *tokens, @@ -944,6 +952,11 @@ static int sof_control_load_volume(struct snd_soc_component *scomp, } out: + /* set up possible led control from mixer private data */ + ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens, + ARRAY_SIZE(led_tokens), mc->priv.array, + le32_to_cpu(mc->priv.size)); + dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", scontrol->comp_id, scontrol->num_channels); From patchwork Mon Feb 24 01:13:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Wang X-Patchwork-Id: 1242781 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48Qkbb5yZwz9sSD; Mon, 24 Feb 2020 12:13:47 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1j62Jc-0005vP-3Y; Mon, 24 Feb 2020 01:13:44 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62Ja-0005uV-UA for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:42 +0000 Received: from [123.112.111.131] (helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j62Ja-0000vQ-1j for kernel-team@lists.ubuntu.com; Mon, 24 Feb 2020 01:13:42 +0000 From: Hui Wang To: kernel-team@lists.ubuntu.com Subject: [SRU][Focal][PATCH 4/4] ASoC: SOF: topology: check errors when parsing LED tokens Date: Mon, 24 Feb 2020 09:13:11 +0800 Message-Id: <20200224011311.7178-5-hui.wang@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200224011311.7178-1-hui.wang@canonical.com> References: <20200224011311.7178-1-hui.wang@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Pierre-Louis Bossart BugLink: https://bugs.launchpad.net/bugs/1864398 sof_parse_tokens() returns a value that is checked on every call except for LED tokens, fix with explicit test. Detected with cppcheck warning: sound/soc/sof/topology.c:973:6: style: Variable 'ret' is assigned a value that is never used. [unreadVariable] ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens, ^ Fixes: 5d43001ae4360 ("ASoC: SOF: acpi led support for switch controls") Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191011164312.7988-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown (cherry picked from commit 8a3ab38c36926ddbda3d2a3086c0a741fa175cff) Signed-off-by: Hui Wang --- sound/soc/sof/topology.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 76e126b533a8..4e1a83cb9b48 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -956,6 +956,11 @@ static int sof_control_load_volume(struct snd_soc_component *scomp, ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens, ARRAY_SIZE(led_tokens), mc->priv.array, le32_to_cpu(mc->priv.size)); + if (ret != 0) { + dev_err(sdev->dev, "error: parse led tokens failed %d\n", + le32_to_cpu(mc->priv.size)); + return ret; + } dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", scontrol->comp_id, scontrol->num_channels);