From patchwork Wed Jun 22 07:46:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890272 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B3609C43334 for ; Wed, 22 Jun 2022 07:48:29 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id F2B371F4A; Wed, 22 Jun 2022 09:47:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz F2B371F4A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884108; bh=gt5eb2S+PuIJ2e/blrKEuVSWfGXnJ8VXq9Dbwir4lkY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=S4h6ea7E9zgrDw7Xt/kPNhWWqyOif3V0S5k2KTSt80z2g4KoZnBBRKo1xkwPDn43E iAasiN2vWJly8dm1uIdYSVtg/kDALcMkOhc/iksCvX+Msu1maeacXDiKBPFqUIW981 m0BZhBqxhQBk/WFqtDX7k7BGrymgqfekTRFgfMOc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 9FF06F80424; Wed, 22 Jun 2022 09:47:12 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EB8A6F8019B; Wed, 22 Jun 2022 09:47:05 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 8E881F8019B for ; Wed, 22 Jun 2022 09:46:57 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 8E881F8019B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="p2SdKHgl" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M6wRdi014511; Wed, 22 Jun 2022 02:46:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=19zBbVWd5UQuD5z83ln7nLLvmxRQYQez1dYLGhgvRWg=; b=p2SdKHglLdneUzElJNVov9aSpqjNzrUKSSue0FLYOO8obAKJnR3oD8s1GosNGEixDM2I qz/9fIbN0KAiE6VgnxZnQ67q2k3oBI4zncz7vV+ggyWybZD7rrILillSYHghDSCcTFKd +6GOFkcQDtowAiMAJEFtf8YuduFyTV+4OrERJOO141xJtP6483A07oyUasUPC6rJIj3+ 6KHn4OseUNBOHRuwQ8kz/dxNRBmnUSd4wfU+ktwC9cRfOh/tk3LsAp9yOXcMq4aad9gd ll19DH9m65I9+nMSoRua5pBxKd51+kRXecm32QMedF9VFeDlZTU7iptCIis4uFllWIvT QQ== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3gsb4p4mwn-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:46:56 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:54 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:54 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id CCC597C; Wed, 22 Jun 2022 07:46:53 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 01/14] ALSA: hda: hda_cs_dsp_ctl: Add Library to support CS_DSP ALSA controls Date: Wed, 22 Jun 2022 08:46:40 +0100 Message-ID: <20220622074653.179078-2-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: tEjL3Y1U8bwbA_LxSkw545vqJgyGPsar X-Proofpoint-ORIG-GUID: tEjL3Y1U8bwbA_LxSkw545vqJgyGPsar X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding The cs35l41 part contains a DSP which is able to run firmware. The cs_dsp library can be used to control the DSP. These controls can be exposed to userspace using ALSA controls. This library adds apis to be able to interface between cs_dsp and hda drivers and expose the relevant controls as ALSA controls. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- MAINTAINERS | 1 + sound/pci/hda/Kconfig | 4 + sound/pci/hda/Makefile | 2 + sound/pci/hda/hda_cs_dsp_ctl.c | 207 +++++++++++++++++++++++++++++++++ sound/pci/hda/hda_cs_dsp_ctl.h | 33 ++++++ 5 files changed, 247 insertions(+) create mode 100644 sound/pci/hda/hda_cs_dsp_ctl.c create mode 100644 sound/pci/hda/hda_cs_dsp_ctl.h diff --git a/MAINTAINERS b/MAINTAINERS index c49b3552f977..fabdd0981ba7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4799,6 +4799,7 @@ S: Maintained F: Documentation/devicetree/bindings/sound/cirrus,cs* F: include/dt-bindings/sound/cs* F: sound/pci/hda/cs* +F: sound/pci/hda/hda_cs_dsp_ctl.* F: sound/soc/codecs/cs* CIRRUS LOGIC DSP FIRMWARE DRIVER diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 79ade4787d95..d1fd6cf82beb 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -94,6 +94,10 @@ config SND_HDA_PATCH_LOADER config SND_HDA_SCODEC_CS35L41 tristate +config SND_HDA_CS_DSP_CONTROLS + tristate + depends on CS_DSP + config SND_HDA_SCODEC_CS35L41_I2C tristate "Build CS35L41 HD-audio side codec support for I2C Bus" depends on I2C diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 3e7bc608d45f..00d306104484 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -31,6 +31,7 @@ snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o snd-hda-scodec-cs35l41-objs := cs35l41_hda.o snd-hda-scodec-cs35l41-i2c-objs := cs35l41_hda_i2c.o snd-hda-scodec-cs35l41-spi-objs := cs35l41_hda_spi.o +snd-hda-cs-dsp-ctls-objs := hda_cs_dsp_ctl.o # common driver obj-$(CONFIG_SND_HDA) := snd-hda-codec.o @@ -54,6 +55,7 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o +obj-$(CONFIG_SND_HDA_CS_DSP_CONTROLS) += snd-hda-cs-dsp-ctls.o # this must be the last entry after codec drivers; # otherwise the codec patches won't be hooked before the PCI probe diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c new file mode 100644 index 000000000000..0f4f02e0a538 --- /dev/null +++ b/sound/pci/hda/hda_cs_dsp_ctl.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// HDA DSP ALSA Control Driver +// +// Copyright 2022 Cirrus Logic, Inc. +// +// Author: Stefan Binding + +#include +#include +#include +#include +#include "hda_cs_dsp_ctl.h" + +#define ADSP_MAX_STD_CTRL_SIZE 512 + +struct hda_cs_dsp_coeff_ctl { + const char *name; + struct cs_dsp_coeff_ctl *cs_ctl; + struct snd_card *card; + struct snd_kcontrol *kctl; +}; + +static const char * const hda_cs_dsp_fw_text[HDA_CS_DSP_NUM_FW] = { + [HDA_CS_DSP_FW_SPK_PROT] = "Prot", + [HDA_CS_DSP_FW_SPK_CALI] = "Cali", + [HDA_CS_DSP_FW_SPK_DIAG] = "Diag", + [HDA_CS_DSP_FW_MISC] = "Misc", +}; + +static int hda_cs_dsp_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) +{ + struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)kctl->private_value; + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = cs_ctl->len; + + return 0; +} + +static int hda_cs_dsp_coeff_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)kctl->private_value; + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + char *p = ucontrol->value.bytes.data; + int ret = 0; + + mutex_lock(&cs_ctl->dsp->pwr_lock); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; +} + +static int hda_cs_dsp_coeff_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)kctl->private_value; + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + char *p = ucontrol->value.bytes.data; + int ret; + + mutex_lock(&cs_ctl->dsp->pwr_lock); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; +} + +static unsigned int wmfw_convert_flags(unsigned int in) +{ + unsigned int out, rd, wr, vol; + + rd = SNDRV_CTL_ELEM_ACCESS_READ; + wr = SNDRV_CTL_ELEM_ACCESS_WRITE; + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; + + out = 0; + + if (in) { + out |= rd; + if (in & WMFW_CTL_FLAG_WRITEABLE) + out |= wr; + if (in & WMFW_CTL_FLAG_VOLATILE) + out |= vol; + } else { + out |= rd | wr | vol; + } + + return out; +} + +static int hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl) +{ + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + struct snd_kcontrol_new *kcontrol; + struct snd_kcontrol *kctl; + int ret = 0; + + if (cs_ctl->len > ADSP_MAX_STD_CTRL_SIZE) { + dev_err(cs_ctl->dsp->dev, "Control %s: length %zu exceeds maximum %d\n", ctl->name, + cs_ctl->len, ADSP_MAX_STD_CTRL_SIZE); + return -EINVAL; + } + + kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); + if (!kcontrol) + return -ENOMEM; + + kcontrol->name = ctl->name; + kcontrol->info = hda_cs_dsp_coeff_info; + kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kcontrol->private_value = (unsigned long)ctl; + kcontrol->access = wmfw_convert_flags(cs_ctl->flags); + + kcontrol->get = hda_cs_dsp_coeff_get; + kcontrol->put = hda_cs_dsp_coeff_put; + + kctl = snd_ctl_new1(kcontrol, NULL); + if (!kctl) { + ret = -ENOMEM; + goto err; + } + ctl->kctl = kctl; + + ret = snd_ctl_add(ctl->card, kctl); + if (ret) + dev_err(cs_ctl->dsp->dev, "Failed to add KControl: %s - Ret: %d\n", kcontrol->name, + ret); + else + dev_dbg(cs_ctl->dsp->dev, "Added KControl: %s\n", kcontrol->name); + +err: + kfree(kcontrol); + + return ret; +} + +int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info) +{ + struct cs_dsp *cs_dsp = cs_ctl->dsp; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + struct hda_cs_dsp_coeff_ctl *ctl; + const char *region_name; + int ret; + + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0; + + region_name = cs_dsp_mem_region_name(cs_ctl->alg_region.type); + if (!region_name) { + dev_err(cs_dsp->dev, "Unknown region type: %d\n", cs_ctl->alg_region.type); + return -EINVAL; + } + + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %.12s %x", info->device_name, + cs_dsp->name, hda_cs_dsp_fw_text[info->fw_type], cs_ctl->alg_region.alg); + + if (cs_ctl->subname) { + int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; + int skip = 0; + + /* Truncate the subname from the start if it is too long */ + if (cs_ctl->subname_len > avail) + skip = cs_ctl->subname_len - avail; + + snprintf(name + ret, SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, + " %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip); + } + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; + ctl->cs_ctl = cs_ctl; + ctl->card = info->card; + + ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); + if (!ctl->name) { + ret = -ENOMEM; + dev_err(cs_dsp->dev, "Cannot save ctl name\n"); + goto err_ctl; + } + + cs_ctl->priv = ctl; + + return hda_cs_dsp_add_kcontrol(ctl); + +err_ctl: + dev_err(cs_dsp->dev, "Error adding control: %s\n", name); + kfree(ctl); + return ret; +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_add, SND_HDA_CS_DSP_CONTROLS); + +void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) +{ + struct hda_cs_dsp_coeff_ctl *ctl = cs_ctl->priv; + + snd_ctl_remove_id(ctl->card, &ctl->kctl->id); + kfree(ctl->name); + kfree(ctl); +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); + +MODULE_DESCRIPTION("CS_DSP ALSA Control HDA Library"); +MODULE_AUTHOR("Stefan Binding, "); +MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h new file mode 100644 index 000000000000..1c6d0fc9a2cc --- /dev/null +++ b/sound/pci/hda/hda_cs_dsp_ctl.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * HDA DSP ALSA Control Driver + * + * Copyright 2022 Cirrus Logic, Inc. + * + * Author: Stefan Binding + */ + +#ifndef __HDA_CS_DSP_CTL_H__ +#define __HDA_CS_DSP_CTL_H__ + +#include +#include + +enum hda_cs_dsp_fw_id { + HDA_CS_DSP_FW_SPK_PROT, + HDA_CS_DSP_FW_SPK_CALI, + HDA_CS_DSP_FW_SPK_DIAG, + HDA_CS_DSP_FW_MISC, + HDA_CS_DSP_NUM_FW +}; + +struct hda_cs_dsp_ctl_info { + struct snd_card *card; + enum hda_cs_dsp_fw_id fw_type; + const char *device_name; +}; + +int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); +void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); + +#endif /*__HDA_CS_DSP_CTL_H__*/ From patchwork Wed Jun 22 07:46:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890273 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 29F37C433EF for ; Wed, 22 Jun 2022 07:48:50 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 41E901F7A; Wed, 22 Jun 2022 09:47:58 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 41E901F7A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884128; bh=fRadHtKHf06s2d3yNDcmudWpzOeCLpVWPm93eVouMPk=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=VSiJUFOgifJXxW3pS5s5XxsWaNbD5+aKkhtzI9LXstj+J7ACXHuHZfovGid/EvALO 7SnwNS0YDTVq+8eTrbNL5SmR0snuOryt5t3NV8VgNcbYZthV1YDLaI2BQRSs9yKO8u TDAFqvNx6z7ZPDwC0UPN0QytD4hY0c5kENx+GfAE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id DBE6EF8032D; Wed, 22 Jun 2022 09:47:13 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id EAD46F804AB; Wed, 22 Jun 2022 09:47:10 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 2ED4BF804AB for ; Wed, 22 Jun 2022 09:46:59 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2ED4BF804AB Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="EXoa0KMM" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nidW032367; Wed, 22 Jun 2022 02:46:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=RNYk4UBGUtNXwVtJjqkoxDLehd0DQef6Q3E9pMtrqrY=; b=EXoa0KMMlgw6zfYYJxEv1e12t+PCKDHso+qjtQ5uwHh3cEbiTMdTL4aKgrV36UlXPA+Y Z7rht0cWT4QzAA6v25FGcwPuDLP2E9HDf6DtWGKpMlVaOsjVHTy+bLPYQVI/HxnrZEi4 iW7rA2RVnAcDGhYXuUZjka2Zg86gir7WFYK51ep9/OxJdDfSCRX2yQr0HIEv2qRG+7F+ tklZkJAS2T2PnjpjRaZMYDgQlXUw9fHYOLujmT3GspKkmmk+3Eskx9Zb3HyEgWrg31SB 6tRzu38m4g3WjvvqRZ0DBqlrka/o32qeO/S7439YjTOXXMNBvCanXU2+8Hdbgy4LKN5P XA== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:46:56 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:54 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:54 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 880E6478; Wed, 22 Jun 2022 07:46:54 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 02/14] ALSA: hda: hda_cs_dsp_ctl: Add apis to write the controls directly Date: Wed, 22 Jun 2022 08:46:41 +0100 Message-ID: <20220622074653.179078-3-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: esAER2oeOn3cMVmogS318zXP7xBlXlL_ X-Proofpoint-ORIG-GUID: esAER2oeOn3cMVmogS318zXP7xBlXlL_ X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding DSP controls are exposed as ALSA controls, however, some of these controls are required to be accessed by the driver. Add apis which allow read/write of these controls. The write api will also notify the ALSA control on value change. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/hda_cs_dsp_ctl.c | 39 ++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_cs_dsp_ctl.h | 4 ++++ 2 files changed, 43 insertions(+) diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c index 0f4f02e0a538..91e37cb916dd 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.c +++ b/sound/pci/hda/hda_cs_dsp_ctl.c @@ -202,6 +202,45 @@ void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) } EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); +int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, const void *buf, size_t len) +{ + struct cs_dsp_coeff_ctl *cs_ctl; + struct hda_cs_dsp_coeff_ctl *ctl; + int ret; + + cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL; + + ctl = cs_ctl->priv; + + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); + if (ret) + return ret; + + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0; + + snd_ctl_notify(ctl->card, SNDRV_CTL_EVENT_MASK_VALUE, &ctl->kctl->id); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, SND_HDA_CS_DSP_CONTROLS); + +int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) +{ + struct cs_dsp_coeff_ctl *cs_ctl; + + cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL; + + return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_read_ctl, SND_HDA_CS_DSP_CONTROLS); + MODULE_DESCRIPTION("CS_DSP ALSA Control HDA Library"); MODULE_AUTHOR("Stefan Binding, "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h index 1c6d0fc9a2cc..c65bfd6878fd 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.h +++ b/sound/pci/hda/hda_cs_dsp_ctl.h @@ -29,5 +29,9 @@ struct hda_cs_dsp_ctl_info { int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); +int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, const void *buf, size_t len); +int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len); #endif /*__HDA_CS_DSP_CTL_H__*/ From patchwork Wed Jun 22 07:46:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890276 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BCDB6CCA47A for ; Wed, 22 Jun 2022 07:49:40 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 02B201FCB; Wed, 22 Jun 2022 09:48:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 02B201FCB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884179; bh=A4F3irbALAhC/GCQes48ypaoVtNjmk+bwUDp2aoragc=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=f3TEzQ9ZO+7UEk/jl+weHaH1jS6srqwIBrQ5wgtIMGdy0+oIrL90P6A1BXjcEOy5A jbfwXuVN9c4nythjuPtKZGc56/itIA+yKPIUVJfFzWKz194Qdx1OC2EtzDMH3dP1DN ffNcfe3TlP4JAKt0MNic0YOlwH4fCsMvr4+TR18k= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id C3E3AF804AC; Wed, 22 Jun 2022 09:47:19 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 19201F8053E; Wed, 22 Jun 2022 09:47:13 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 075FDF802D2 for ; Wed, 22 Jun 2022 09:46:59 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 075FDF802D2 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="GATqspGd" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nidX032367; Wed, 22 Jun 2022 02:46:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=VCfSQqByA7jNBXTSiZFxlNUN/rTeTM0AlDQs0otcWSg=; b=GATqspGdEpi06VV0io8ZvKA76qG5QJj9en6yUY3C3OrVsI1PGrqdvvEsdCeOx1dcoU1W AnQmK1JKuxd5vUc+ZqfgNzaYAksC+5AFb5G2RfkXYMR0eyaCokVDMRFEdEJxMBvUaJ/z ShDY36C9O5A64pzO92YYk0K/z3utgjo/3Tw6A1QJCNAKzu/R+voIcQJSbfLIMJpGEcYa 6uPpr9M++gPABmkvJzwFSMwyN4lRxJRBfM8wsNOQYlTbiz+SNS1a663oJlmf8AcIbW19 1SeX3HvaPqTSLrZVrdBaDOLclfR/OER5PiWjClc5nve+fMwr/mikOY0i2AFQW/AXsSxV qQ== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:46:57 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:55 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:55 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id D61D57C; Wed, 22 Jun 2022 07:46:54 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 03/14] ALSA: hda: cs35l41: Save codec object inside component struct Date: Wed, 22 Jun 2022 08:46:42 +0100 Message-ID: <20220622074653.179078-4-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: mhus3BjgP_rz4Qi0NknL8g6wCIYzp619 X-Proofpoint-ORIG-GUID: mhus3BjgP_rz4Qi0NknL8g6wCIYzp619 X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding This is required for ALSA control support. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 1 + sound/pci/hda/cs35l41_hda.h | 1 + sound/pci/hda/hda_component.h | 1 + sound/pci/hda/patch_realtek.c | 1 + 4 files changed, 4 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index cce27a86267f..bbbaafac50c3 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -117,6 +117,7 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas return -EBUSY; comps->dev = dev; + cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); comps->playback_hook = cs35l41_hda_playback_hook; diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index a52ffd1f7999..aaf9e16684c2 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -32,6 +32,7 @@ struct cs35l41_hda { struct regmap *regmap; struct gpio_desc *reset_gpio; struct cs35l41_hw_cfg hw_cfg; + struct hda_codec *codec; int irq; int index; diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h index e26c896a13f3..534e845b9cd1 100644 --- a/sound/pci/hda/hda_component.h +++ b/sound/pci/hda/hda_component.h @@ -14,5 +14,6 @@ struct hda_component { struct device *dev; char name[HDA_MAX_NAME_SIZE]; + struct hda_codec *codec; void (*playback_hook)(struct device *dev, int action); }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ff9a09a670ed..923c0d498d54 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6654,6 +6654,7 @@ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char "%s-%s:00-cs35l41-hda.%d", bus, hid, i); if (!name) return; + spec->comps[i].codec = cdc; component_match_add(dev, &spec->match, component_compare_dev_name, name); } ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); From patchwork Wed Jun 22 07:46:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890274 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6C916C433EF for ; Wed, 22 Jun 2022 07:48:58 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B74311F98; Wed, 22 Jun 2022 09:48:06 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B74311F98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884136; bh=AP7JjIzXVIRqT/Zk3ThV0MLwloaFhbMX5+rTBQvbqWE=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=U0MM0RDeedXVpJiLOJObvWbvdTkSUn02upkJbqnUyfq2WdBqFn+edGOuDW7+oWvTf BkN3dMdUXbAeNiWa4jF3/WxkdvuHxBPNSzCDhd4XEEkDFX9ZRJPBUGlYLfCp8+odal g9PJ37HCasAGHPPaHZLQRVskK6zIeg0YQf//zGQk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 6EB65F80543; Wed, 22 Jun 2022 09:47:15 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 47FC8F8053A; Wed, 22 Jun 2022 09:47:11 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id D5ECCF80424 for ; Wed, 22 Jun 2022 09:47:00 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D5ECCF80424 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="YGHESPHr" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M7kwSh003806; Wed, 22 Jun 2022 02:46:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=l/wxdow08RjQlc8G74wnUPmR8RpCTX0YZGMsHn0P5Mw=; b=YGHESPHrBUV8IEE5VwVfkTXBfRGJlrD9219qUfocP6jiVKOtbFBRkVa5b0veT8on2GcW zMfZ5H0NAVzDfOKHig+vrWK0y/IotBvcH5EsLf66mWrQXWEqrzidpSIYvtCKBgi8gfky as2LLj0vySfasJjje8TlFFp7UCmvDUL9fYqzvN73yMG4QeBBNc8v8gA3e0UO+YtupOvX ackP6uSQZloVBnMC/QblB9Fb8EPzbYIZU5lwNh3zRKLoAak0iQhL8C42v7YaE569pgzH SERb5vL2eAfY3jXHrXL1t4x9lzcjdEu5dBPVJJNUXr3VvMs/onCdsJ7yyl+BqE6zQJUM Dg== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:46:58 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:56 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:56 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 9FF4F478; Wed, 22 Jun 2022 07:46:55 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , "Mark Brown" Subject: [PATCH v7 04/14] ALSA: hda: cs35l41: Add initial DSP support and firmware loading Date: Wed, 22 Jun 2022 08:46:43 +0100 Message-ID: <20220622074653.179078-5-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: MPuB8j4HeGRzWCFE82eaNYUotOu6MLhI X-Proofpoint-ORIG-GUID: MPuB8j4HeGRzWCFE82eaNYUotOu6MLhI X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Vitaly Rodionov X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Vitaly Rodionov This patch adds support for the CS35L41 DSP. The DSP allows for extra features, such as running speaker protection algorithms and hibernations. To utilize these features, the driver must load firmware into the DSP, as well as various tuning files which allow for customization for specific models. Signed-off-by: Vitaly Rodionov Signed-off-by: Vitaly Rodionov --- include/sound/cs35l41.h | 4 + sound/pci/hda/Kconfig | 4 + sound/pci/hda/cs35l41_hda.c | 252 +++++++++++++++++++++++++++++++++++- sound/pci/hda/cs35l41_hda.h | 13 ++ 4 files changed, 272 insertions(+), 1 deletion(-) diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index a66ef37184fd..9ac5918269a5 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -665,6 +665,10 @@ #define CS35L41_BST_EN_DEFAULT 0x2 #define CS35L41_AMP_EN_SHIFT 0 #define CS35L41_AMP_EN_MASK 1 +#define CS35L41_VMON_EN_MASK 0x1000 +#define CS35L41_VMON_EN_SHIFT 12 +#define CS35L41_IMON_EN_MASK 0x2000 +#define CS35L41_IMON_EN_SHIFT 13 #define CS35L41_PDN_DONE_MASK 0x00800000 #define CS35L41_PDN_DONE_SHIFT 23 diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index d1fd6cf82beb..1c378cca5dac 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -106,6 +106,8 @@ config SND_HDA_SCODEC_CS35L41_I2C select SND_HDA_GENERIC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 + select SND_HDA_CS_DSP_CONTROLS + select CS_DSP select REGMAP_IRQ help Say Y or M here to include CS35L41 I2C HD-audio side codec support @@ -122,6 +124,8 @@ config SND_HDA_SCODEC_CS35L41_SPI select SND_HDA_GENERIC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 + select SND_HDA_CS_DSP_CONTROLS + select CS_DSP select REGMAP_IRQ help Say Y or M here to include CS35L41 SPI HD-audio side codec support diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index bbbaafac50c3..92c6d8b7052e 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -9,12 +9,22 @@ #include #include #include +#include #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" #include "hda_generic.h" #include "hda_component.h" #include "cs35l41_hda.h" +#include "hda_cs_dsp_ctl.h" + +#define CS35L41_FIRMWARE_ROOT "cirrus/" +#define CS35L41_PART "cs35l41" +#define FW_NAME "CSPL" + +#define HALO_STATE_DSP_CTL_NAME "HALO_STATE" +#define HALO_STATE_DSP_CTL_TYPE 5 +#define HALO_STATE_DSP_CTL_ALG 262308 static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 @@ -27,11 +37,173 @@ static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB }; +static const struct reg_sequence cs35l41_hda_config_dsp[] = { + { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 + { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN + { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz + { CS35L41_SP_ENABLES, 0x00010001 }, // ASP_RX1_EN = 1, ASP_TX1_EN = 1 + { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz + { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer + { CS35L41_SP_HIZ_CTRL, 0x00000003 }, // Hi-Z unused/disabled + { CS35L41_SP_TX_WL, 0x00000018 }, // 24 cycles/slot + { CS35L41_SP_RX_WL, 0x00000018 }, // 24 cycles/slot + { CS35L41_DAC_PCM1_SRC, 0x00000032 }, // DACPCM1_SRC = ERR_VOL + { CS35L41_ASP_TX1_SRC, 0x00000018 }, // ASPTX1 SRC = VMON + { CS35L41_ASP_TX2_SRC, 0x00000019 }, // ASPTX2 SRC = IMON + { CS35L41_ASP_TX3_SRC, 0x00000028 }, // ASPTX3 SRC = VPMON + { CS35L41_ASP_TX4_SRC, 0x00000029 }, // ASPTX4 SRC = VBSTMON + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, // DSP1RX1 SRC = ASPRX1 + { CS35L41_DSP1_RX2_SRC, 0x00000008 }, // DSP1RX2 SRC = ASPRX1 + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON + { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON + { CS35L41_DSP1_RX5_SRC, 0x00000029 }, // DSP1RX5 SRC = VBSTMON + { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB + { CS35L41_AMP_GAIN_CTRL, 0x00000233 }, // AMP_GAIN_PCM = 17.5dB AMP_GAIN_PDM = 19.5dB +}; + static const struct reg_sequence cs35l41_hda_mute[] = { { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, // AMP_GAIN_PCM 0.5 dB { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute }; +static int cs35l41_control_add(struct cs_dsp_coeff_ctl *cs_ctl) +{ + struct cs35l41_hda *cs35l41 = container_of(cs_ctl->dsp, struct cs35l41_hda, cs_dsp); + struct hda_cs_dsp_ctl_info info; + + info.device_name = cs35l41->amp_name; + info.fw_type = HDA_CS_DSP_FW_SPK_PROT; + info.card = cs35l41->codec->card; + + return hda_cs_dsp_control_add(cs_ctl, &info); +} + +static const struct cs_dsp_client_ops client_ops = { + .control_add = cs35l41_control_add, + .control_remove = hda_cs_dsp_control_remove, +}; + +static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, + const struct firmware **firmware, char **filename, + const char *dir, const char *filetype) +{ + const char * const dsp_name = cs35l41->cs_dsp.name; + char *s, c; + int ret = 0; + + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", + filetype); + + if (*filename == NULL) + return -ENOMEM; + + /* + * Make sure that filename is lower-case and any non alpha-numeric + * characters except full stop and '/' are replaced with hyphens. + */ + s = *filename; + while (*s) { + c = *s; + if (isalnum(c)) + *s = tolower(c); + else if (c != '.' && c != '/') + *s = '-'; + s++; + } + + ret = firmware_request_nowarn(firmware, *filename, cs35l41->dev); + if (ret != 0) { + dev_dbg(cs35l41->dev, "Failed to request '%s'\n", *filename); + kfree(*filename); + *filename = NULL; + } + + return ret; +} + +static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, + const struct firmware **wmfw_firmware, + char **wmfw_filename, + const struct firmware **coeff_firmware, + char **coeff_filename) +{ + int ret; + + /* cirrus/part-dspN-fwtype.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, "wmfw"); + if (!ret) { + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, "bin"); + return 0; + } + + dev_warn(cs35l41->dev, "Failed to request firmware\n"); + + return ret; +} + + +static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) +{ + const struct firmware *coeff_firmware = NULL; + const struct firmware *wmfw_firmware = NULL; + struct cs_dsp *dsp = &cs35l41->cs_dsp; + char *coeff_filename = NULL; + char *wmfw_filename = NULL; + int ret; + + if (!cs35l41->halo_initialized) { + cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, dsp); + dsp->client_ops = &client_ops; + + ret = cs_dsp_halo_init(&cs35l41->cs_dsp); + if (ret) + return ret; + cs35l41->halo_initialized = true; + } + + ret = cs35l41_request_firmware_files(cs35l41, &wmfw_firmware, &wmfw_filename, + &coeff_firmware, &coeff_filename); + if (ret < 0) + return ret; + + dev_dbg(cs35l41->dev, "Loading WMFW Firmware: %s\n", wmfw_filename); + if (coeff_filename) + dev_dbg(cs35l41->dev, "Loading Coefficient File: %s\n", coeff_filename); + else + dev_warn(cs35l41->dev, "No Coefficient File available.\n"); + + ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, + FW_NAME); + + release_firmware(wmfw_firmware); + release_firmware(coeff_firmware); + kfree(wmfw_filename); + kfree(coeff_filename); + + return ret; +} + +static void cs35l41_shutdown_dsp(struct cs35l41_hda *cs35l41) +{ + struct cs_dsp *dsp = &cs35l41->cs_dsp; + + cs_dsp_stop(dsp); + cs_dsp_power_down(dsp); + cs35l41->firmware_running = false; + dev_dbg(cs35l41->dev, "Unloaded Firmware\n"); +} + +static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) +{ + struct cs_dsp *dsp = &cs35l41->cs_dsp; + + cs35l41_shutdown_dsp(cs35l41); + cs_dsp_remove(dsp); + cs35l41->halo_initialized = false; +} + /* Protection release cycle to get the speaker out of Safe-Mode */ static void cs35l41_error_release(struct device *dev, struct regmap *regmap, unsigned int mask) { @@ -53,9 +225,22 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) struct regmap *reg = cs35l41->regmap; int ret = 0; + mutex_lock(&cs35l41->fw_mutex); + switch (action) { case HDA_GEN_PCM_ACT_OPEN: - regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config)); + if (cs35l41->firmware_running) { + regmap_multi_reg_write(reg, cs35l41_hda_config_dsp, + ARRAY_SIZE(cs35l41_hda_config_dsp)); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK, + 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT); + cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, + CSPL_MBOX_CMD_RESUME); + } else { + regmap_multi_reg_write(reg, cs35l41_hda_config, + ARRAY_SIZE(cs35l41_hda_config)); + } ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) @@ -73,6 +258,13 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001); + if (cs35l41->firmware_running) { + cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, + CSPL_MBOX_CMD_PAUSE); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK, + 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT); + } cs35l41_irq_release(cs35l41); break; default: @@ -80,6 +272,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) break; } + mutex_unlock(&cs35l41->fw_mutex); + if (ret) dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); } @@ -104,6 +298,51 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi rx_slot); } +static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) +{ + int halo_sts; + int ret; + + ret = cs35l41_init_dsp(cs35l41); + if (ret) { + dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret); + goto clean_dsp; + } + + ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write FS Errata: %d\n", ret); + goto clean_dsp; + } + + ret = cs_dsp_run(&cs35l41->cs_dsp); + if (ret) { + dev_err(cs35l41->dev, "Fail to start dsp: %d\n", ret); + goto clean_dsp; + } + + ret = read_poll_timeout(hda_cs_dsp_read_ctl, ret, + be32_to_cpu(halo_sts) == HALO_STATE_CODE_RUN, + 1000, 15000, false, &cs35l41->cs_dsp, HALO_STATE_DSP_CTL_NAME, + HALO_STATE_DSP_CTL_TYPE, HALO_STATE_DSP_CTL_ALG, + &halo_sts, sizeof(halo_sts)); + + if (ret) { + dev_err(cs35l41->dev, "Timeout waiting for HALO Core to start. State: %d\n", + halo_sts); + goto clean_dsp; + } + + cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, CSPL_MBOX_CMD_PAUSE); + cs35l41->firmware_running = true; + + return 0; + +clean_dsp: + cs35l41_shutdown_dsp(cs35l41); + return ret; +} + static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); @@ -121,6 +360,11 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas strscpy(comps->name, dev_name(dev), sizeof(comps->name)); comps->playback_hook = cs35l41_hda_playback_hook; + mutex_lock(&cs35l41->fw_mutex); + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); + mutex_unlock(&cs35l41->fw_mutex); + return 0; } @@ -537,6 +781,8 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i if (ret) goto err; + mutex_init(&cs35l41->fw_mutex); + ret = cs35l41_hda_apply_properties(cs35l41); if (ret) goto err; @@ -564,6 +810,9 @@ void cs35l41_hda_remove(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + if (cs35l41->halo_initialized) + cs35l41_remove_dsp(cs35l41); + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) @@ -573,5 +822,6 @@ void cs35l41_hda_remove(struct device *dev) EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); MODULE_DESCRIPTION("CS35L41 HDA Driver"); +MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index aaf9e16684c2..5814af050944 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -15,6 +15,9 @@ #include #include +#include +#include + enum cs35l41_hda_spk_pos { CS35l41_LEFT, CS35l41_RIGHT, @@ -39,7 +42,17 @@ struct cs35l41_hda { int channel_index; unsigned volatile long irq_errors; const char *amp_name; + struct mutex fw_mutex; struct regmap_irq_chip_data *irq_data; + bool firmware_running; + bool halo_initialized; + struct cs_dsp cs_dsp; +}; + +enum halo_state { + HALO_STATE_CODE_INIT_DOWNLOAD = 0, + HALO_STATE_CODE_START, + HALO_STATE_CODE_RUN }; int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, From patchwork Wed Jun 22 07:46:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890277 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B3645C43334 for ; Wed, 22 Jun 2022 07:49:51 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id EE8DE1FA1; Wed, 22 Jun 2022 09:48:59 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EE8DE1FA1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884190; bh=9JciEPK6uWn/59WK5lSBpQ7C30B3/2JPu4ukaeQEqes=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=j1FMk6y6AuogAMeG9Mx3hBEyzEkkzvSkPXA+i3CKvxSSqmoZfWf76ZqP05H/uBCfi f1zjuXaXH83sTxI9x/it2RjN+pzvSLW2I4Sy/FT7BVhPve6d7U7I/dic7jZtBSKHnH 8s1nnb3/4KAH/pI8GICU2CbWMoGDUiL3w5Es64WY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id CE1D7F80566; Wed, 22 Jun 2022 09:47:20 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2879FF8053A; Wed, 22 Jun 2022 09:47:13 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id C0C15F80100 for ; Wed, 22 Jun 2022 09:47:00 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz C0C15F80100 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="DPw+5kdb" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nidY032367; Wed, 22 Jun 2022 02:46:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=R/t6fc1SxxcbNSxZ8Yw6JojVc/MfujfdPc5svZLK/5I=; b=DPw+5kdbjnyL83p7kdzvNXNpkTuuTPLsYYZlvD8phULF7+psmlH4hSHRk8tYTX3WhoLf yZgslwlUX3AjV/S/7lx2f9NPnInwxP7QuiomNhNxHcL3QEtwlgm8WoRaS8JUsSmLpsNc 7DUhHoV2iJWrfNV9ymbulc1t9uPK53SycL36wPWZwbx4koTa+FmvfCJXT5DyJizmakS6 MyJKthc6oNxrzA0hWZ4kAX6/dQ/DRa5lbHJ+4ZZDU3mg8u/zUS61Hq3IUD7SV5zwlHt+ 0p28CBpoUZLoLXF4eFBlSUGBVPR5ls/1r97v9HUfODf8R0O2bvp/IAawCYsREooeMXPI rw== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:46:58 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:56 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:56 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 6A51D7C; Wed, 22 Jun 2022 07:46:56 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 05/14] ALSA: hda: cs35l41: Save Subsystem ID inside CS35L41 Driver Date: Wed, 22 Jun 2022 08:46:44 +0100 Message-ID: <20220622074653.179078-6-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: Gl2YTIcckGdZ8GLssjQD23JeEoaqKRdl X-Proofpoint-ORIG-GUID: Gl2YTIcckGdZ8GLssjQD23JeEoaqKRdl X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding The Subsystem ID is read from the HDA driver, and will be used by the CS35L41 driver to be able to uniquely identify the laptop, which is required to be able to define firmware to be used by specific models. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 3 +++ sound/pci/hda/cs35l41_hda.h | 1 + sound/pci/hda/hda_component.h | 1 + sound/pci/hda/patch_realtek.c | 1 + 4 files changed, 6 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 92c6d8b7052e..7f0132694774 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -356,6 +356,9 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas return -EBUSY; comps->dev = dev; + if (!cs35l41->acpi_subsystem_id) + cs35l41->acpi_subsystem_id = devm_kasprintf(dev, GFP_KERNEL, + "%.8x", comps->subsystem_id); cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); comps->playback_hook = cs35l41_hda_playback_hook; diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index 5814af050944..b57f59a1ba49 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -42,6 +42,7 @@ struct cs35l41_hda { int channel_index; unsigned volatile long irq_errors; const char *amp_name; + const char *acpi_subsystem_id; struct mutex fw_mutex; struct regmap_irq_chip_data *irq_data; bool firmware_running; diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h index 534e845b9cd1..fa6df52e7855 100644 --- a/sound/pci/hda/hda_component.h +++ b/sound/pci/hda/hda_component.h @@ -14,6 +14,7 @@ struct hda_component { struct device *dev; char name[HDA_MAX_NAME_SIZE]; + int subsystem_id; struct hda_codec *codec; void (*playback_hook)(struct device *dev, int action); }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 923c0d498d54..6a944396582b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6655,6 +6655,7 @@ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char if (!name) return; spec->comps[i].codec = cdc; + spec->comps[i].subsystem_id = cdc->core.subsystem_id; component_match_add(dev, &spec->match, component_compare_dev_name, name); } ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); From patchwork Wed Jun 22 07:46:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890278 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7938BCCA47D for ; Wed, 22 Jun 2022 07:50:13 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id C6E581FAB; Wed, 22 Jun 2022 09:49:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C6E581FAB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884211; bh=ZHe3WzHKLG1yz7u1v8gHNJSxOQImrKgIYukZojDBmok=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=cFy7/G8tTRbXzN63Tg4k1AGxpmweUAD6w+pcDKp7xf2GXmknPSv/yRANBWIeff4/r bKwGUP5mEz9QKSF41rctedq3eOO9n5zhxSoc0acpJIjz5AD5prSasIANFU+KAr/FIu OAQKRjK94fsMy7lZTFtoPaqeJcrGTSUuEPJ4A3es= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id CB9A7F80537; Wed, 22 Jun 2022 09:47:25 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 28E9AF80544; Wed, 22 Jun 2022 09:47:16 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 139D0F80482 for ; Wed, 22 Jun 2022 09:47:01 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 139D0F80482 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="CsN0FVX8" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nidZ032367; Wed, 22 Jun 2022 02:46:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=22fxRs36mOwLx01C6ew27/L9/hScJO9HrYMwPcvStzY=; b=CsN0FVX8qWGBEs6jEBgned8gXqz6VMrDW3eOp5IL7JTKa6wY0MPsRUDYXMIZKqwvqA20 9oju4WDQPbDLd9v7Hw6fd8XdaoiPYASkePGdd9ZKETnX5KcYfnK0DSikRsoP2yqEMx1k tRLClce9XGfmxCpFT7DsGSG8oANh6R3iFQya0NNzQjueuwfbC4B5fsfkDKxXpddoEjP2 ZFL0qCNVev5fVGYqaUW6C2VT1Ju8EAOub6oey8V/RnFRnLqor+ayEC8JFROMhJalJ8zE Lm1IDLjztZwDvOdsEaGIORBRp9s/AQo7L76S10gW6WUD5fn9JZ17Yfg5qG/ZYCEXp078 pg== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:46:59 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:56 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:56 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id B15E2478; Wed, 22 Jun 2022 07:46:56 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 06/14] ALSA: hda: cs35l41: Support reading subsystem id from ACPI Date: Wed, 22 Jun 2022 08:46:45 +0100 Message-ID: <20220622074653.179078-7-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: tDt8dgkqh7FuI2KRjUiMRInTDRDIjvLZ X-Proofpoint-ORIG-GUID: tDt8dgkqh7FuI2KRjUiMRInTDRDIjvLZ X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding On some laptop models, the ACPI contains the unique Subsystem ID, and this value should be preferred over the value from the HDA driver. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 7f0132694774..5f89a0462eb6 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -545,6 +545,36 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); } +static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *adev, + const char **subsysid) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + acpi_status status; + int ret = 0; + + status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer); + if (ACPI_SUCCESS(status)) { + obj = buffer.pointer; + if (obj->type == ACPI_TYPE_STRING) { + *subsysid = devm_kstrdup(dev, obj->string.pointer, GFP_KERNEL); + if (*subsysid == NULL) { + dev_err(dev, "Cannot allocate Subsystem ID"); + ret = -ENOMEM; + } + } else { + dev_warn(dev, "Warning ACPI _SUB did not return a string\n"); + ret = -ENODEV; + } + acpi_os_free(buffer.pointer); + } else { + dev_dbg(dev, "Warning ACPI _SUB failed: %#x\n", status); + ret = -ENODEV; + } + + return ret; +} + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) { struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; @@ -564,6 +594,12 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i physdev = get_device(acpi_get_first_physical_node(adev)); acpi_dev_put(adev); + ret = cs35l41_get_acpi_sub_string(cs35l41->dev, adev, &cs35l41->acpi_subsystem_id); + if (ret) + dev_info(cs35l41->dev, "No Subsystem ID found in ACPI: %d", ret); + else + dev_dbg(cs35l41->dev, "Subsystem ID %s found", cs35l41->acpi_subsystem_id); + property = "cirrus,dev-index"; ret = device_property_count_u32(physdev, property); if (ret <= 0) From patchwork Wed Jun 22 07:46:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890280 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 93E36C43334 for ; Wed, 22 Jun 2022 07:50:41 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id BCB03200C; Wed, 22 Jun 2022 09:49:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BCB03200C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884239; bh=SzceSpTg6sKuZh7S87kvktG8GfTHtg3Bg5hd7573RzU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Bgwr3dfLKZ8CzEbCUmV1v2MlZ7YH064vIFnmVyUgQ+3FW2PQJusbI7L2drilotc1i vNtx4G7FYmMHGOKxBzvFhUv8JlnnwoOwMTivf38w/ZYk9N0+izBRaJPdb5GDxB34qU 7RNdfbI+zuJRbe9MHcELC8ibr9OmwSXCxInc8RQw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 1AFA4F8057C; Wed, 22 Jun 2022 09:47:27 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 22FD2F80553; Wed, 22 Jun 2022 09:47:17 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 8B6ECF800CB for ; Wed, 22 Jun 2022 09:47:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 8B6ECF800CB Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="n9kYdNQs" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nida032367; Wed, 22 Jun 2022 02:47:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=aJ+qVBFEqeWjFo1nmDAZ4IDre8eujRV2kDvfK/OYYG0=; b=n9kYdNQsD4g/GlYxp7uJ/volVdacUHrOJH70dEcqMwYDNZ3rOv7dawNiKS0Y7CSuejMC zn/2sG8Hu5DJEF3iXGIeZA1C6dXHpM3JnW1BTPMrWXDm9gI4ImI0/bd2vLjZq4hgBNNd PTOOBWOqwCLKB9/sp7zVZgSPEOaFGQ3P6bp5jyRG21gxMhV6U2n961Iha9q1ZWafRWT5 Ny5XGeGpdIvP1i8XBxtYF5mbm0SsEWkTxDqDCjt2PQEN/QOMuQXZS9dnLHV8cM7V1Nlg T3i0RixORQ5q7EIa1q1LhrElCrFL8Qsi/YVYdXf5lBUxuK3hZjMpYaxojQqeX2A/H1t0 PQ== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:46:59 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:57 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:57 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 088CA11D1; Wed, 22 Jun 2022 07:46:57 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 07/14] ALSA: hda: cs35l41: Support multiple load paths for firmware Date: Wed, 22 Jun 2022 08:46:46 +0100 Message-ID: <20220622074653.179078-8-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: L9SRHaEqBuuN6BmMWQCPhgHj5A1SW7jB X-Proofpoint-ORIG-GUID: L9SRHaEqBuuN6BmMWQCPhgHj5A1SW7jB X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding To be able to support different firmwares and tuning for different models, the driver needs to be able to load a different firmware and coefficient file based on its Subsystem ID. The driver attempts to load the firmware in the following order: /lib/firmware/cirrus/cs35l41-dsp1---dev<#>.wmfw /lib/firmware/cirrus/cs35l41-dsp1--.wmfw /lib/firmware/cirrus/cs35l41-dsp1-.wmfw Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 53 ++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 5f89a0462eb6..6d90bb8f74ea 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -85,14 +85,23 @@ static const struct cs_dsp_client_ops client_ops = { static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, const struct firmware **firmware, char **filename, - const char *dir, const char *filetype) + const char *dir, const char *ssid, const char *amp_name, + const char *filetype) { const char * const dsp_name = cs35l41->cs_dsp.name; char *s, c; int ret = 0; - *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", - filetype); + if (ssid && amp_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, amp_name, + filetype); + else if (ssid) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, filetype); + else + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", filetype); if (*filename == NULL) return -ENOMEM; @@ -129,12 +138,43 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, { int ret; - /* cirrus/part-dspN-fwtype.wmfw */ + /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, - CS35L41_FIRMWARE_ROOT, "wmfw"); + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + NULL, "wmfw"); if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ + ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + cs35l41->amp_name, "bin"); + if (ret) + /* try cirrus/part-dspN-fwtype-sub.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, NULL, "bin"); + return 0; + } + + /* fallback try cirrus/part-dspN-fwtype.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, NULL, NULL, "wmfw"); + if (!ret) { + /* fallback try cirrus/part-dspN-fwtype.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, - CS35L41_FIRMWARE_ROOT, "bin"); + CS35L41_FIRMWARE_ROOT, NULL, NULL, "bin"); return 0; } @@ -143,7 +183,6 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, return ret; } - static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) { const struct firmware *coeff_firmware = NULL; From patchwork Wed Jun 22 07:46:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890279 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7588BC433EF for ; Wed, 22 Jun 2022 07:50:28 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id CAFBD1FD2; Wed, 22 Jun 2022 09:49:36 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz CAFBD1FD2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884226; bh=fWWQdr94vqQ22zSXgDabYfb0y1tKbOl5QuOKHrgJF3s=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=KTdsi1EM7CIJc0CQ38jdDpIYyWv0FftUNILY+IQt6mTn3KCuKZkBlgtghWKeAvsEq lTvscYHCmWK/ClzOOlPAQNpsxQy5eOCHBaI1ypWZfn/+HWhVxO/DfvNLuFjt6PzQL/ ni5QC+NyY4cPCcpcbVrC6uUgo1a2Rg2cpxD2P9Zo= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 77265F80570; Wed, 22 Jun 2022 09:47:26 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0B8AFF8054A; Wed, 22 Jun 2022 09:47:16 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 14037F80534 for ; Wed, 22 Jun 2022 09:47:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 14037F80534 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="RCMKbGTs" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nidb032367; Wed, 22 Jun 2022 02:47:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=sI8SX3PB/R2fNl6PH3oFh+Fy/DogbIVBHrE/v2Q5jyw=; b=RCMKbGTsBeAsOJCuxZEVfXiGVGiN6Ad0kG0JrDH/0o1bGNCvMtxKrP4c3x3ahUDl5nEK noq16r4P31Bsia+Ah6SCRu1MooYiYPl055ZfWO29rsOQCOrE0/H7hwLJlVZAmfVbl0OC afP4DTcpJJdfoBv+wpB04JxsjoJr245rEvf7qoPOKnE3Ics6rqmOHIkbFnID5P8SdULR xTaeFiOf48IJCAVsSDbgmVi/yo1EO/2PVtGKub9gs3W5XB/EDS0pGyTNUKHAeKKArr08 DVDBCphqomSutK9/yVxyRMQ5lrYWNoKO2aKZWFbuBvDZ6dnEIWXkn7TTy8o5jj4Bg1XO sA== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:47:00 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:57 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:57 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 9AA87478; Wed, 22 Jun 2022 07:46:57 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 08/14] ALSA: hda: cs35l41: Support Speaker ID for laptops Date: Wed, 22 Jun 2022 08:46:47 +0100 Message-ID: <20220622074653.179078-9-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: R4ka3m1d-wv8BGYbOnEHKFdrvW9avxZD X-Proofpoint-ORIG-GUID: R4ka3m1d-wv8BGYbOnEHKFdrvW9avxZD X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Some Laptops use a number of gpios to define which vendor is used for a particular laptop. Different coefficient files are used for different vendors. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 174 ++++++++++++++++++++++++++++++++++-- sound/pci/hda/cs35l41_hda.h | 1 + 2 files changed, 166 insertions(+), 9 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 6d90bb8f74ea..6ac68b00cafe 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -86,13 +86,19 @@ static const struct cs_dsp_client_ops client_ops = { static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, const struct firmware **firmware, char **filename, const char *dir, const char *ssid, const char *amp_name, - const char *filetype) + int spkid, const char *filetype) { const char * const dsp_name = cs35l41->cs_dsp.name; char *s, c; int ret = 0; - if (ssid && amp_name) + if (spkid > -1 && ssid && amp_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, spkid, amp_name, filetype); + else if (spkid > -1 && ssid) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, spkid, filetype); + else if (ssid && amp_name) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", ssid, amp_name, filetype); @@ -130,6 +136,93 @@ static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, return ret; } +static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41, + const struct firmware **wmfw_firmware, + char **wmfw_filename, + const struct firmware **coeff_firmware, + char **coeff_filename) +{ + int ret; + + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, cs35l41->amp_name, + cs35l41->speaker_id, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, cs35l41->amp_name, + cs35l41->speaker_id, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, -1, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, cs35l41->speaker_id, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub<-spkidN>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + NULL, cs35l41->speaker_id, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + cs35l41->amp_name, cs35l41->speaker_id, "bin"); + if (ret) + /* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + NULL, cs35l41->speaker_id, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + NULL, -1, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + cs35l41->amp_name, cs35l41->speaker_id, "bin"); + if (ret) + /* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + NULL, cs35l41->speaker_id, "bin"); + return 0; + } + + /* fallback try cirrus/part-dspN-fwtype.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw"); + if (!ret) { + /* fallback try cirrus/part-dspN-fwtype.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin"); + return 0; + } + + dev_warn(cs35l41->dev, "Failed to request firmware\n"); + + return ret; +} + static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, const struct firmware **wmfw_firmware, char **wmfw_filename, @@ -138,43 +231,48 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, { int ret; + if (cs35l41->speaker_id > -1) + return cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename); + /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - cs35l41->amp_name, "wmfw"); + cs35l41->amp_name, -1, "wmfw"); if (!ret) { /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - cs35l41->amp_name, "bin"); + cs35l41->amp_name, -1, "bin"); return 0; } /* try cirrus/part-dspN-fwtype-sub.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - NULL, "wmfw"); + NULL, -1, "wmfw"); if (!ret) { /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - cs35l41->amp_name, "bin"); + cs35l41->amp_name, -1, "bin"); if (ret) /* try cirrus/part-dspN-fwtype-sub.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, CS35L41_FIRMWARE_ROOT, - cs35l41->acpi_subsystem_id, NULL, "bin"); + cs35l41->acpi_subsystem_id, + NULL, -1, "bin"); return 0; } /* fallback try cirrus/part-dspN-fwtype.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, - CS35L41_FIRMWARE_ROOT, NULL, NULL, "wmfw"); + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw"); if (!ret) { /* fallback try cirrus/part-dspN-fwtype.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, - CS35L41_FIRMWARE_ROOT, NULL, NULL, "bin"); + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin"); return 0; } @@ -614,6 +712,61 @@ static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *a return ret; } +static int cs35l41_get_speaker_id(struct device *dev, int amp_index, + int num_amps, int fixed_gpio_id) +{ + struct gpio_desc *speaker_id_desc; + int speaker_id = -ENODEV; + + if (fixed_gpio_id >= 0) { + dev_dbg(dev, "Found Fixed Speaker ID GPIO (index = %d)\n", fixed_gpio_id); + speaker_id_desc = gpiod_get_index(dev, NULL, fixed_gpio_id, GPIOD_IN); + if (IS_ERR(speaker_id_desc)) { + speaker_id = PTR_ERR(speaker_id_desc); + return speaker_id; + } + speaker_id = gpiod_get_value_cansleep(speaker_id_desc); + gpiod_put(speaker_id_desc); + dev_dbg(dev, "Speaker ID = %d\n", speaker_id); + } else { + int base_index; + int gpios_per_amp; + int count; + int tmp; + int i; + + count = gpiod_count(dev, "spk-id"); + if (count > 0) { + speaker_id = 0; + gpios_per_amp = count / num_amps; + base_index = gpios_per_amp * amp_index; + + if (count % num_amps) + return -EINVAL; + + dev_dbg(dev, "Found %d Speaker ID GPIOs per Amp\n", gpios_per_amp); + + for (i = 0; i < gpios_per_amp; i++) { + speaker_id_desc = gpiod_get_index(dev, "spk-id", i + base_index, + GPIOD_IN); + if (IS_ERR(speaker_id_desc)) { + speaker_id = PTR_ERR(speaker_id_desc); + break; + } + tmp = gpiod_get_value_cansleep(speaker_id_desc); + gpiod_put(speaker_id_desc); + if (tmp < 0) { + speaker_id = tmp; + break; + } + speaker_id |= tmp << i; + } + dev_dbg(dev, "Speaker ID = %d\n", speaker_id); + } + } + return speaker_id; +} + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) { struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; @@ -719,6 +872,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i else hw_cfg->bst_cap = -1; + cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, nval, -1); + if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) hw_cfg->bst_type = CS35L41_INT_BOOST; else @@ -752,6 +907,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i cs35l41->channel_index = 0; cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; + cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; hw_cfg->gpio2.valid = true; cs35l41->hw_cfg.valid = true; diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index b57f59a1ba49..a9dbc1c19248 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -43,6 +43,7 @@ struct cs35l41_hda { unsigned volatile long irq_errors; const char *amp_name; const char *acpi_subsystem_id; + int speaker_id; struct mutex fw_mutex; struct regmap_irq_chip_data *irq_data; bool firmware_running; From patchwork Wed Jun 22 07:46:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890285 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 48410CCA47A for ; Wed, 22 Jun 2022 07:52:00 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 71DF2245A; Wed, 22 Jun 2022 09:51:08 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 71DF2245A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884318; bh=oW3VSIkEJFuVG5DIifE398Rp9SR+TzGnTnljujkWB+4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ZiYFw/rAdA+gOsusvDFZ4KZYxregrBy0mMiDJydsOkg7/+c8UfglIRjgNEJac9UYW kNM1dRYn+O1o3bEFKbW6ato4yicx46R2d7ru6CYfgvJ01mfOY+Y/wFtscdPcdtCOxc SJoMyjzBlIhTcYR1uj9h3FAB1JW0zRNRnUpvQH2Y= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 58CC6F805B6; Wed, 22 Jun 2022 09:47:30 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 102B4F8056F; Wed, 22 Jun 2022 09:47:24 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 64C68F80538 for ; Wed, 22 Jun 2022 09:47:03 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 64C68F80538 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="VE3kwIw1" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nidc032367; Wed, 22 Jun 2022 02:47:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=6FMRzWnU6tXGH/Y5SQA0XSGsZk9aXVh9Y/FKlXcq3QE=; b=VE3kwIw1ATG8CkBTDH/UiKHyGPCB8CWOM+SZrPzEoab80eMrkAW+egOzoyrKz2zKc10F czV0e/E9QzYN1hhlildXfupqjzkY/CivpNOnB7Lm5AaLoapvVm79Rn76AjB2x6G60uSH uZtfg7ikj6KhHQabHqns0CU9NGeLIcXTWBn+BWVsFDtev0ZuKE0u5bn5IB6/pD8QRQ4X PeqG7wr4MNO70yGAzozTcpDGSEvrwTcVFdL7yyIAQPj6qbc4fWCjNE63TmzFHsKfIpGq tzLFa2nSFDV2hsaKiq/PfaMmeVF7b7YIoJXEF7MsMqFz+3CqFob6Q6xUDOr8T/WT5hlW hw== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:47:01 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:58 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:58 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id E938F7C; Wed, 22 Jun 2022 07:46:57 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 09/14] ALSA: hda: cs35l41: Support Hibernation during Suspend Date: Wed, 22 Jun 2022 08:46:48 +0100 Message-ID: <20220622074653.179078-10-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: HINZRMZbXhFjFEVaZ0NSiW7dn8ma5UF6 X-Proofpoint-ORIG-GUID: HINZRMZbXhFjFEVaZ0NSiW7dn8ma5UF6 X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding CS35L41 supports hibernation during suspend when using DSP firmware. When the driver suspends it will hibernate the part, if firmware is running, and resume will wake from hibernation. CS35L41 driver will suspend/resume when requested by hda driver. Note that suspend/resume and hibernation is only supported when firmware is running. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 109 +++++++++++++++++++++++++++++++- sound/pci/hda/cs35l41_hda.h | 2 + sound/pci/hda/cs35l41_hda_i2c.c | 1 + sound/pci/hda/cs35l41_hda_spi.c | 1 + sound/pci/hda/hda_component.h | 2 + sound/pci/hda/patch_realtek.c | 25 +++++++- 6 files changed, 136 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 6ac68b00cafe..b502806fbfa1 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" @@ -435,6 +436,75 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi rx_slot); } +static int cs35l41_runtime_suspend(struct device *dev) +{ + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + + dev_dbg(cs35l41->dev, "Suspend\n"); + + if (!cs35l41->firmware_running) + return 0; + + if (cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type) < 0) + return 0; + + regcache_cache_only(cs35l41->regmap, true); + regcache_mark_dirty(cs35l41->regmap); + + return 0; +} + +static int cs35l41_runtime_resume(struct device *dev) +{ + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + int ret; + + dev_dbg(cs35l41->dev, "Resume.\n"); + + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { + dev_dbg(cs35l41->dev, "System does not support Resume\n"); + return 0; + } + + if (!cs35l41->firmware_running) + return 0; + + regcache_cache_only(cs35l41->regmap, false); + + ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); + if (ret) { + regcache_cache_only(cs35l41->regmap, true); + return ret; + } + + /* Test key needs to be unlocked to allow the OTP settings to re-apply */ + cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); + ret = regcache_sync(cs35l41->regmap); + cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); + if (ret) { + dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); + return ret; + } + + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) + cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg); + + return 0; +} + +static int cs35l41_hda_suspend_hook(struct device *dev) +{ + dev_dbg(dev, "Request Suspend\n"); + pm_runtime_mark_last_busy(dev); + return pm_runtime_put_autosuspend(dev); +} + +static int cs35l41_hda_resume_hook(struct device *dev) +{ + dev_dbg(dev, "Request Resume\n"); + return pm_runtime_get_sync(dev); +} + static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) { int halo_sts; @@ -492,19 +562,27 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas if (comps->dev) return -EBUSY; + pm_runtime_get_sync(dev); + comps->dev = dev; if (!cs35l41->acpi_subsystem_id) cs35l41->acpi_subsystem_id = devm_kasprintf(dev, GFP_KERNEL, "%.8x", comps->subsystem_id); cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); - comps->playback_hook = cs35l41_hda_playback_hook; mutex_lock(&cs35l41->fw_mutex); if (cs35l41_smart_amp(cs35l41) < 0) dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); mutex_unlock(&cs35l41->fw_mutex); + comps->playback_hook = cs35l41_hda_playback_hook; + comps->suspend_hook = cs35l41_hda_suspend_hook; + comps->resume_hook = cs35l41_hda_resume_hook; + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; } @@ -600,7 +678,7 @@ static const struct regmap_irq cs35l41_reg_irqs[] = { CS35L41_REG_IRQ(IRQ1_STATUS1, AMP_SHORT_ERR), }; -static const struct regmap_irq_chip cs35l41_regmap_irq_chip = { +static struct regmap_irq_chip cs35l41_regmap_irq_chip = { .name = "cs35l41 IRQ1 Controller", .status_base = CS35L41_IRQ1_STATUS1, .mask_base = CS35L41_IRQ1_MASK1, @@ -608,6 +686,7 @@ static const struct regmap_irq_chip cs35l41_regmap_irq_chip = { .num_regs = 4, .irqs = cs35l41_reg_irqs, .num_irqs = ARRAY_SIZE(cs35l41_reg_irqs), + .runtime_pm = true, }; static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) @@ -1017,13 +1096,23 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i mutex_init(&cs35l41->fw_mutex); + pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); + pm_runtime_use_autosuspend(cs35l41->dev); + pm_runtime_mark_last_busy(cs35l41->dev); + pm_runtime_set_active(cs35l41->dev); + pm_runtime_get_noresume(cs35l41->dev); + pm_runtime_enable(cs35l41->dev); + ret = cs35l41_hda_apply_properties(cs35l41); if (ret) - goto err; + goto err_pm; + + pm_runtime_put_autosuspend(cs35l41->dev); ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); if (ret) { dev_err(cs35l41->dev, "Register component failed: %d\n", ret); + pm_runtime_disable(cs35l41->dev); goto err; } @@ -1031,6 +1120,10 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i return 0; +err_pm: + pm_runtime_disable(cs35l41->dev); + pm_runtime_put_noidle(cs35l41->dev); + err: if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); @@ -1044,17 +1137,27 @@ void cs35l41_hda_remove(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + pm_runtime_get_sync(cs35l41->dev); + pm_runtime_disable(cs35l41->dev); + if (cs35l41->halo_initialized) cs35l41_remove_dsp(cs35l41); component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + pm_runtime_put_noidle(cs35l41->dev); + if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); gpiod_put(cs35l41->reset_gpio); } EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); +const struct dev_pm_ops cs35l41_hda_pm_ops = { + SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) +}; +EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41); + MODULE_DESCRIPTION("CS35L41 HDA Driver"); MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index a9dbc1c19248..439c4b705328 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -57,6 +57,8 @@ enum halo_state { HALO_STATE_CODE_RUN }; +extern const struct dev_pm_ops cs35l41_hda_pm_ops; + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, struct regmap *regmap); void cs35l41_hda_remove(struct device *dev); diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c index e810b278fb91..a669090a18e8 100644 --- a/sound/pci/hda/cs35l41_hda_i2c.c +++ b/sound/pci/hda/cs35l41_hda_i2c.c @@ -55,6 +55,7 @@ static struct i2c_driver cs35l41_i2c_driver = { .driver = { .name = "cs35l41-hda", .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), + .pm = &cs35l41_hda_pm_ops, }, .id_table = cs35l41_hda_i2c_id, .probe = cs35l41_hda_i2c_probe, diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c index 22e088f28438..d7f15e2abe66 100644 --- a/sound/pci/hda/cs35l41_hda_spi.c +++ b/sound/pci/hda/cs35l41_hda_spi.c @@ -50,6 +50,7 @@ static struct spi_driver cs35l41_spi_driver = { .driver = { .name = "cs35l41-hda", .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), + .pm = &cs35l41_hda_pm_ops, }, .id_table = cs35l41_hda_spi_id, .probe = cs35l41_hda_spi_probe, diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h index fa6df52e7855..72ec0d865a28 100644 --- a/sound/pci/hda/hda_component.h +++ b/sound/pci/hda/hda_component.h @@ -17,4 +17,6 @@ struct hda_component { int subsystem_id; struct hda_codec *codec; void (*playback_hook)(struct device *dev, int action); + int (*suspend_hook)(struct device *dev); + int (*resume_hook)(struct device *dev); }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6a944396582b..cf06b12a24c1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4021,15 +4021,22 @@ static void alc5505_dsp_init(struct hda_codec *codec) static int alc269_suspend(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + int i; if (spec->has_alc5505_dsp) alc5505_dsp_suspend(codec); + + for (i = 0; i < HDA_MAX_COMPONENTS; i++) + if (spec->comps[i].suspend_hook) + spec->comps[i].suspend_hook(spec->comps[i].dev); + return alc_suspend(codec); } static int alc269_resume(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + int i; if (spec->codec_variant == ALC269_TYPE_ALC269VB) alc269vb_toggle_power_output(codec, 0); @@ -4060,6 +4067,10 @@ static int alc269_resume(struct hda_codec *codec) if (spec->has_alc5505_dsp) alc5505_dsp_resume(codec); + for (i = 0; i < HDA_MAX_COMPONENTS; i++) + if (spec->comps[i].resume_hook) + spec->comps[i].resume_hook(spec->comps[i].dev); + return 0; } #endif /* CONFIG_PM */ @@ -6610,8 +6621,20 @@ static int comp_bind(struct device *dev) { struct hda_codec *cdc = dev_to_hda_codec(dev); struct alc_spec *spec = cdc->spec; + int ret, i; + + ret = component_bind_all(dev, spec->comps); + if (ret) + return ret; - return component_bind_all(dev, spec->comps); + if (snd_hdac_is_power_on(&cdc->core)) { + codec_dbg(cdc, "Resuming after bind.\n"); + for (i = 0; i < HDA_MAX_COMPONENTS; i++) + if (spec->comps[i].resume_hook) + spec->comps[i].resume_hook(spec->comps[i].dev); + } + + return 0; } static void comp_unbind(struct device *dev) From patchwork Wed Jun 22 07:46:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890275 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B20E9C43334 for ; Wed, 22 Jun 2022 07:49:21 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id F03AE1FB5; Wed, 22 Jun 2022 09:48:29 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz F03AE1FB5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884160; bh=6iQRmPx602q5SuJpVWU7woYmXLF6DVL4LPOeX1XpbvQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=atMwt1wFdo7CDzqO642fJIWvrhcrERG7bJP32WBWlJwiK8Yuhne6tNfsKD4XAhVYj 22a0DAxAWMnNdb7ewRn85qg59O6XGpqVYoov7nYjFkA1ZottQQmSva7RSBhCbKRH1g jzD6OM5HUhBpsE4CLVEvf0z0rwV2Nm5UwN4g0z18= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5F880F80552; Wed, 22 Jun 2022 09:47:17 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B6063F8053D; Wed, 22 Jun 2022 09:47:12 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 10DD4F8032D for ; Wed, 22 Jun 2022 09:47:01 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 10DD4F8032D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="gjwesCkA" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M7Su1M003738; Wed, 22 Jun 2022 02:47:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=EbmHX6Pf2odyNfINmfGSummXzA3kLvVccKNYAHBOj+4=; b=gjwesCkALfjYAoFwfxhxg0dUGiXV3O6jRfwiWdYybxRYAJ6XS7qE3zjPuJDWEcJfWjt/ 0xq3YEcWJCOGhqMj9uXNAxRMwgjGUDJwT+xKWQ/QqTzohGai/4bioHxX6tJYhsq+GIoA F1LtHCAQgnu6WQ6nyEgNS6Lax7BP3i88OH7ICe80mtGV+pNrRiG2CH5Y3nZaU7DTl3cL 3DX2ock21C29cjqFwjwex7F0AeNbGdgaBOTQdBqNhMSGOpwIr78J85SXD6RymzItCggP SqyJqO87JC/Y3vJtTIqO909adYPIbQ2wZAvf0YREZZitA9sJuznz1XvhOqnlwAfYIqyD 9w== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3gsb4p4mwq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:47:00 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:58 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:58 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 8C648478; Wed, 22 Jun 2022 07:46:58 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 10/14] ALSA: hda: cs35l41: Read Speaker Calibration data from UEFI variables Date: Wed, 22 Jun 2022 08:46:49 +0100 Message-ID: <20220622074653.179078-11-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: HiKe5hv_p9tmNDT3VIIFWHs8-_mUBsZR X-Proofpoint-ORIG-GUID: HiKe5hv_p9tmNDT3VIIFWHs8-_mUBsZR X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Speaker Calibration data, specific to an individual speaker is stored inside UEFI variables during calibration, and can be used by the DSP. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 101 ++++++++++++++++++++++++++++++++++++ sound/pci/hda/cs35l41_hda.h | 15 ++++++ 2 files changed, 116 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index b502806fbfa1..ef3dfda7b03e 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -26,6 +26,12 @@ #define HALO_STATE_DSP_CTL_NAME "HALO_STATE" #define HALO_STATE_DSP_CTL_TYPE 5 #define HALO_STATE_DSP_CTL_ALG 262308 +#define CAL_R_DSP_CTL_NAME "CAL_R" +#define CAL_STATUS_DSP_CTL_NAME "CAL_STATUS" +#define CAL_CHECKSUM_DSP_CTL_NAME "CAL_CHECKSUM" +#define CAL_AMBIENT_DSP_CTL_NAME "CAL_AMBIENT" +#define CAL_DSP_CTL_TYPE 5 +#define CAL_DSP_CTL_ALG 205 static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 @@ -282,6 +288,96 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, return ret; } +#if IS_ENABLED(CONFIG_EFI) +static int cs35l41_apply_calibration(struct cs35l41_hda *cs35l41, unsigned int ambient, + unsigned int r0, unsigned int status, unsigned int checksum) +{ + int ret; + + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_AMBIENT_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &ambient, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_AMBIENT_DSP_CTL_NAME, + ret); + return ret; + } + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_R_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &r0, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_R_DSP_CTL_NAME, ret); + return ret; + } + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_STATUS_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &status, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_STATUS_DSP_CTL_NAME, + ret); + return ret; + } + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_CHECKSUM_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &checksum, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_CHECKSUM_DSP_CTL_NAME, + ret); + return ret; + } + + return 0; +} + +static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) +{ + static efi_guid_t efi_guid = EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, + 0x5a, 0xa3, 0x5d, 0xb3); + static efi_char16_t efi_name[] = L"CirrusSmartAmpCalibrationData"; + const struct cs35l41_amp_efi_data *efi_data; + const struct cs35l41_amp_cal_data *cl; + unsigned long data_size = 0; + efi_status_t status; + int ret = 0; + u8 *data = NULL; + u32 attr; + + /* Get real size of UEFI variable */ + status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data); + if (status == EFI_BUFFER_TOO_SMALL) { + ret = -ENODEV; + /* Allocate data buffer of data_size bytes */ + data = vmalloc(data_size); + if (!data) + return -ENOMEM; + /* Get variable contents into buffer */ + status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data); + if (status == EFI_SUCCESS) { + efi_data = (struct cs35l41_amp_efi_data *)data; + dev_dbg(cs35l41->dev, "Calibration: Size=%d, Amp Count=%d\n", + efi_data->size, efi_data->count); + if (efi_data->count > cs35l41->index) { + cl = &efi_data->data[cs35l41->index]; + dev_dbg(cs35l41->dev, + "Calibration: Ambient=%02x, Status=%02x, R0=%d\n", + cl->calAmbient, cl->calStatus, cl->calR); + + /* Calibration can only be applied whilst the DSP is not running */ + ret = cs35l41_apply_calibration(cs35l41, + cpu_to_be32(cl->calAmbient), + cpu_to_be32(cl->calR), + cpu_to_be32(cl->calStatus), + cpu_to_be32(cl->calR + 1)); + } + } + vfree(data); + } + return ret; +} +#else +static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) +{ + dev_warn(cs35l41->dev, "Calibration not supported without EFI support.\n"); + return 0; +} +#endif + static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) { const struct firmware *coeff_firmware = NULL; @@ -314,7 +410,12 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, FW_NAME); + if (ret) + goto err_release; + + ret = cs35l41_save_calibration(cs35l41); +err_release: release_firmware(wmfw_firmware); release_firmware(coeff_firmware); kfree(wmfw_filename); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index 439c4b705328..59a9461d0444 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -10,6 +10,7 @@ #ifndef __CS35L41_HDA_H__ #define __CS35L41_HDA_H__ +#include #include #include #include @@ -18,6 +19,20 @@ #include #include +struct cs35l41_amp_cal_data { + u32 calTarget[2]; + u32 calTime[2]; + s8 calAmbient; + u8 calStatus; + u16 calR; +} __packed; + +struct cs35l41_amp_efi_data { + u32 size; + u32 count; + struct cs35l41_amp_cal_data data[]; +} __packed; + enum cs35l41_hda_spk_pos { CS35l41_LEFT, CS35l41_RIGHT, From patchwork Wed Jun 22 07:46:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890282 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 50224C433EF for ; Wed, 22 Jun 2022 07:51:12 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9D06A2022; Wed, 22 Jun 2022 09:50:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9D06A2022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884270; bh=/tmlKFpQsU/5wYS+N2VeJGBxUW4oj0NWzl7gLJnkEYk=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=YvUdzra6nSQhK98+q3shJyDY+hRTkIVd8/6NZ2glAS6xG0zGFzychnPJRU7hzj7BW fltN19gLWNI27gVsZ18ZN+CiMt4NqSmlJoGWc6BEVBaumhs3wxWjVplm8/aXHILPCU NXlDzIvKgc4gZodYSYhRRbE+eaBRbr46EyCdI7+g= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id A0663F805A1; Wed, 22 Jun 2022 09:47:28 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B429BF8055B; Wed, 22 Jun 2022 09:47:19 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CE862F804AC for ; Wed, 22 Jun 2022 09:47:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CE862F804AC Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="KKZDWZG5" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M7Su1N003738; Wed, 22 Jun 2022 02:47:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=leMMeFw9xjvYsUhcKWCZtXuXd0wyI7t+7bKwC0xfahk=; b=KKZDWZG5bKNjJSSBJIR920A9VbfU72gVRi0akB1iBlKIhS09+M2nadPuyHn9I7yIKA91 ci+q7w4tq9kpjAnHhUk2BWNMLiBTKjWBGnDvt1+xzAfpQuxw701dptRYXKHT/bHQae+j e9293e8Tm9JwiRvXsOJ6msJLwbIGilgJfC35dlJv275b5g7gl4oa2MlbA47tu4jAghAR FHwlkWnvCEkTwVR5MEqzpcLROB4et4vnemdlD8MOdApo+5DSqlk0fx0ZzQ711YGvKvl0 mkG9LHwJRZZCtdYq/giL7Ja8W7y+KAhMthbHcSlbt3RyOklHHYQCMQH5O2KlMc0UsDqS tA== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3gsb4p4mwq-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:47:00 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:59 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:59 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id DE88A11D1; Wed, 22 Jun 2022 07:46:58 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 11/14] ALSA: hda: hda_cs_dsp_ctl: Add fw id strings Date: Wed, 22 Jun 2022 08:46:50 +0100 Message-ID: <20220622074653.179078-12-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: SXEjNAOyj_ojR1VAY7X-TJZXg9otusBc X-Proofpoint-ORIG-GUID: SXEjNAOyj_ojR1VAY7X-TJZXg9otusBc X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding This will be used to define the firmware names. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/hda_cs_dsp_ctl.c | 8 ++++++++ sound/pci/hda/hda_cs_dsp_ctl.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c index 91e37cb916dd..5eac43cf8736 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.c +++ b/sound/pci/hda/hda_cs_dsp_ctl.c @@ -28,6 +28,14 @@ static const char * const hda_cs_dsp_fw_text[HDA_CS_DSP_NUM_FW] = { [HDA_CS_DSP_FW_MISC] = "Misc", }; +const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW] = { + [HDA_CS_DSP_FW_SPK_PROT] = "spk-prot", + [HDA_CS_DSP_FW_SPK_CALI] = "spk-cali", + [HDA_CS_DSP_FW_SPK_DIAG] = "spk-diag", + [HDA_CS_DSP_FW_MISC] = "misc", +}; +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_fw_ids, SND_HDA_CS_DSP_CONTROLS); + static int hda_cs_dsp_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) { struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)kctl->private_value; diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h index c65bfd6878fd..4babc69cf2f0 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.h +++ b/sound/pci/hda/hda_cs_dsp_ctl.h @@ -27,6 +27,8 @@ struct hda_cs_dsp_ctl_info { const char *device_name; }; +extern const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW]; + int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, From patchwork Wed Jun 22 07:46:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890281 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 291F9C433EF for ; Wed, 22 Jun 2022 07:50:54 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 600B61FFE; Wed, 22 Jun 2022 09:50:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 600B61FFE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884252; bh=4osVN2gxBC3rbdED3ZmBiVIVKBbUlu8oCWkt4+YNe6o=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=qQXcggFlcJ5wTw8/Vm5AFY8RbiM4ik2zypwSMPZDjVMeQ0c0Y/1KkfsVVVn30nMVD Oa7oyNL8c/3NCgJuOWiWLveuJtGr1r/4Ez9lJYJxnJd+ThjEnWQPylwPvXSzNPbYR7 egHwiN+PvMzxY06R3vGYkuRYSWYW4lOl0la5h9ek= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 14D0BF80589; Wed, 22 Jun 2022 09:47:28 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 14166F80558; Wed, 22 Jun 2022 09:47:18 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 7CF83F80535 for ; Wed, 22 Jun 2022 09:47:03 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 7CF83F80535 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="NrEYe35O" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M7Su1O003738; Wed, 22 Jun 2022 02:47:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=yEUjvzIDkSuesN4ILaRzVOzgfN/9xKEkJ3H0pI1QULM=; b=NrEYe35OCbFA5K4w3y/h6iCQ33rEWbfuNmpShF8nhhQGgg0RlCVdt9Tn+Bve2J26mLLF GENfcg63ZJ4IBPiv0aBBEZrX3fAiQXNpHFtpszx49M9RG52ASoNkkwFWRTHbmlX9VrIx t2cPHlIpZByDXPm9qMapNjd8GVMXBRrTT2atCtkyj0Dbgk4zn1gAnCMxrseOn6gbAG/t iguSEcUEsF4wsoSRezBFIXz6HhcCR/K5FIq5Qdl7wDONSEwyN2hx5tLKffLE6hXgz1YI zlMhHnO4ZcRnJkTUan4aCIlhyBAaRXJyoBIpPQPaV75fsfDW9qr6bm/HLYtVWKtPiCpl ZA== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3gsb4p4mwq-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:47:01 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:46:59 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:46:59 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 89FD47C; Wed, 22 Jun 2022 07:46:59 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 12/14] ALSA: hda: cs35l41: Add defaulted values into dsp bypass config sequence Date: Wed, 22 Jun 2022 08:46:51 +0100 Message-ID: <20220622074653.179078-13-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: GPYNT5VgfyCEfZnDm8cGUkg_0o_g_PpR X-Proofpoint-ORIG-GUID: GPYNT5VgfyCEfZnDm8cGUkg_0o_g_PpR X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding The config sequences for running with and without firmware and DSP are different. The original behavior assumed that we would only run without DSP only in the case where firmware load failed. This meant the non-firmware sequence was written with the assumtion that various registers would be set to their default value. However, to support the ability to unload the firmware, the non-firmware register sequence must be updated to update all required registers, including values that would be defaulted, in case the firmware sequence, which could have already run, has changed their value. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index ef3dfda7b03e..e51cdf42d3dc 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -35,11 +35,24 @@ static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 + { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz { CS35L41_SP_ENABLES, 0x00010000 }, // ASP_RX1_EN = 1 { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer + { CS35L41_SP_HIZ_CTRL, 0x00000002 }, // Hi-Z unused + { CS35L41_SP_TX_WL, 0x00000018 }, // 24 cycles/slot + { CS35L41_SP_RX_WL, 0x00000018 }, // 24 cycles/slot { CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1 + { CS35L41_ASP_TX1_SRC, 0x00000018 }, // ASPTX1 SRC = VMON + { CS35L41_ASP_TX2_SRC, 0x00000019 }, // ASPTX2 SRC = IMON + { CS35L41_ASP_TX3_SRC, 0x00000032 }, // ASPTX3 SRC = ERRVOL + { CS35L41_ASP_TX4_SRC, 0x00000033 }, // ASPTX4 SRC = CLASSH_TGT + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, // DSP1RX1 SRC = ASPRX1 + { CS35L41_DSP1_RX2_SRC, 0x00000009 }, // DSP1RX2 SRC = ASPRX2 + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON + { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON + { CS35L41_DSP1_RX5_SRC, 0x00000020 }, // DSP1RX5 SRC = ERRVOL { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB }; From patchwork Wed Jun 22 07:46:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890284 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B4801CCA47D for ; Wed, 22 Jun 2022 07:51:41 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 106CD2331; Wed, 22 Jun 2022 09:50:50 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 106CD2331 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884300; bh=e1EPusHm31ZkkD3JRymd2Jd0BRqkGXfRiaXEW6nefX4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=DM4humjyJ5YZRIPx04XoTBUk4icbMnJJ4BrnydwM428c/9bxJZwUgv0d6CRXPJHYz KIBQLBOUzjWswyZ59kzMEf7oK9cVuXnq1l4+YfgUc5CmoSyBl37Mi/8zvOyhOkZzE4 37vMHbgGCvoy+U9c+pyGV4/zEaqpZFhrkiBYNPD8= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id C1002F805B2; Wed, 22 Jun 2022 09:47:29 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 85612F80570; Wed, 22 Jun 2022 09:47:22 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 923E7F80537 for ; Wed, 22 Jun 2022 09:47:04 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 923E7F80537 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="XpGNUrWs" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nidd032367; Wed, 22 Jun 2022 02:47:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=Pix/D3S9OebNgFhFGX/0xJqiIsFZ5HW8wcC6IbYMwgk=; b=XpGNUrWsRV9/8+MpgOJ20wdb2Pkl+lYZA6kU6+4oiY5RvRjVsUB0X7HhXIDEm47xppY+ 1/8dRZkXfatiX3QhJ4r5aNV/wFaUU3eo15F14H7CGBZ5yUpOFPxw5JWFnyfETcAayMs0 Phc/fBmYmmQGhCZDaNxtDDwb2lI84KAi59h42LRV5XsaTQ3DU+kFnUCXoTZGV/0fnrBj Z8VK6OaagF6L4ZPL/N+OoAaStnAq0QxabgvbSCdg5vl0U329uDwEOHwwSBTZOzPxsoCl GTXLmd5Rtj1zRVNdMsMjngXoIauy+D8771/8KPUyAZx9pR4wNwhDjNB/y1GQ5A5XbAAU qQ== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:47:02 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:47:00 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:47:00 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id DE384478; Wed, 22 Jun 2022 07:46:59 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 13/14] ALSA: hda: cs35l41: Support Firmware switching and reloading Date: Wed, 22 Jun 2022 08:46:52 +0100 Message-ID: <20220622074653.179078-14-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: xTBjZkEJaW1tikalfzzoxw00UMMaCtV7 X-Proofpoint-ORIG-GUID: xTBjZkEJaW1tikalfzzoxw00UMMaCtV7 X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding This is required to support CS35L41 calibration. By default, speaker protection firmware will be loaded, if available. However, different firmware is required to run the calibration sequence, so it is necessary to add support to be able to unload, switch and reload firmware. This patch adds 2 ALSA Controls for each amp: "DSP1 Firmware Load" "DSP1 Firmware Type" "DSP1 Firmware Load" can be used to unload and load the firmware. "DSP1 Firmware Type" can be used to switch the target firmware to be loaded by "DSP1 Firmware Load" Since loading firmware can add new ALSA controls, it is necessary to ensure the firmware loading is run asynchronously from the ALSA control itself to prevent deadlocks. Note: When switching between firmwares, an ALSA control is only added if it has not previously existed. If it had existed previously, it will be re-enabled instead. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 201 ++++++++++++++++++++++++++++++++++-- sound/pci/hda/cs35l41_hda.h | 6 ++ 2 files changed, 197 insertions(+), 10 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index e51cdf42d3dc..3aa36c5ff972 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -21,7 +21,6 @@ #define CS35L41_FIRMWARE_ROOT "cirrus/" #define CS35L41_PART "cs35l41" -#define FW_NAME "CSPL" #define HALO_STATE_DSP_CTL_NAME "HALO_STATE" #define HALO_STATE_DSP_CTL_TYPE 5 @@ -92,7 +91,7 @@ static int cs35l41_control_add(struct cs_dsp_coeff_ctl *cs_ctl) struct hda_cs_dsp_ctl_info info; info.device_name = cs35l41->amp_name; - info.fw_type = HDA_CS_DSP_FW_SPK_PROT; + info.fw_type = cs35l41->firmware_type; info.card = cs35l41->codec->card; return hda_cs_dsp_control_add(cs_ctl, &info); @@ -114,20 +113,24 @@ static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, if (spkid > -1 && ssid && amp_name) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, spkid, amp_name, filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, spkid, amp_name, filetype); else if (spkid > -1 && ssid) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, spkid, filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, spkid, filetype); else if (ssid && amp_name) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, amp_name, - filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, amp_name, filetype); else if (ssid) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, filetype); else *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + filetype); if (*filename == NULL) return -ENOMEM; @@ -422,7 +425,7 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) dev_warn(cs35l41->dev, "No Coefficient File available.\n"); ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, - FW_NAME); + hda_cs_dsp_fw_ids[cs35l41->firmware_type]); if (ret) goto err_release; @@ -451,6 +454,7 @@ static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) { struct cs_dsp *dsp = &cs35l41->cs_dsp; + cancel_work_sync(&cs35l41->fw_load_work); cs35l41_shutdown_dsp(cs35l41); cs_dsp_remove(dsp); cs35l41->halo_initialized = false; @@ -481,6 +485,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) switch (action) { case HDA_GEN_PCM_ACT_OPEN: + cs35l41->playback_started = true; if (cs35l41->firmware_running) { regmap_multi_reg_write(reg, cs35l41_hda_config_dsp, ARRAY_SIZE(cs35l41_hda_config_dsp)); @@ -518,6 +523,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT); } cs35l41_irq_release(cs35l41); + cs35l41->playback_started = false; break; default: dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); @@ -664,10 +670,179 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) return ret; } +static void cs35l41_load_firmware(struct cs35l41_hda *cs35l41, bool load) +{ + pm_runtime_get_sync(cs35l41->dev); + + if (cs35l41->firmware_running && !load) { + dev_dbg(cs35l41->dev, "Unloading Firmware\n"); + cs35l41_shutdown_dsp(cs35l41); + } else if (!cs35l41->firmware_running && load) { + dev_dbg(cs35l41->dev, "Loading Firmware\n"); + cs35l41_smart_amp(cs35l41); + } else { + dev_dbg(cs35l41->dev, "Unable to Load firmware.\n"); + } + + pm_runtime_mark_last_busy(cs35l41->dev); + pm_runtime_put_autosuspend(cs35l41->dev); +} + +static int cs35l41_fw_load_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = cs35l41->request_fw_load; + return 0; +} + +static void cs35l41_fw_load_work(struct work_struct *work) +{ + struct cs35l41_hda *cs35l41 = container_of(work, struct cs35l41_hda, fw_load_work); + + mutex_lock(&cs35l41->fw_mutex); + + /* Recheck if playback is ongoing, mutex will block playback during firmware loading */ + if (cs35l41->playback_started) + dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); + else + cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load); + + cs35l41->fw_request_ongoing = false; + mutex_unlock(&cs35l41->fw_mutex); +} + +static int cs35l41_fw_load_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + unsigned int ret = 0; + + mutex_lock(&cs35l41->fw_mutex); + + if (cs35l41->request_fw_load == ucontrol->value.integer.value[0]) + goto err; + + if (cs35l41->fw_request_ongoing) { + dev_dbg(cs35l41->dev, "Existing request not complete\n"); + ret = -EBUSY; + goto err; + } + + /* Check if playback is ongoing when initial request is made */ + if (cs35l41->playback_started) { + dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); + ret = -EBUSY; + goto err; + } + + cs35l41->fw_request_ongoing = true; + cs35l41->request_fw_load = ucontrol->value.integer.value[0]; + schedule_work(&cs35l41->fw_load_work); + +err: + mutex_unlock(&cs35l41->fw_mutex); + + return ret; +} + +static int cs35l41_fw_type_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = cs35l41->firmware_type; + + return 0; +} + +static int cs35l41_fw_type_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + + if (ucontrol->value.enumerated.item[0] < HDA_CS_DSP_NUM_FW) { + cs35l41->firmware_type = ucontrol->value.enumerated.item[0]; + return 0; + } + + return -EINVAL; +} + +static int cs35l41_fw_type_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(hda_cs_dsp_fw_ids), hda_cs_dsp_fw_ids); +} + +static int cs35l41_create_controls(struct cs35l41_hda *cs35l41) +{ + struct snd_kcontrol_new fw_type_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = cs35l41_fw_type_ctl_info, + .get = cs35l41_fw_type_ctl_get, + .put = cs35l41_fw_type_ctl_put, + }; + struct snd_kcontrol_new fw_load_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = snd_ctl_boolean_mono_info, + .get = cs35l41_fw_load_ctl_get, + .put = cs35l41_fw_load_ctl_put, + }; + struct snd_kcontrol *kctl1, *kctl2; + int ret = 0; + + fw_load_ctl.name = kasprintf(GFP_KERNEL, "%s DSP1 Firmware Load", cs35l41->amp_name); + if (!fw_load_ctl.name) { + ret = -ENOMEM; + goto err; + } + + fw_type_ctl.name = kasprintf(GFP_KERNEL, "%s DSP1 Firmware Type", cs35l41->amp_name); + if (!fw_type_ctl.name) { + ret = -ENOMEM; + goto err; + } + + kctl1 = snd_ctl_new1(&fw_type_ctl, cs35l41); + if (!kctl1) { + ret = -ENOMEM; + goto err; + } + if (snd_ctl_add(cs35l41->codec->card, kctl1)) { + ret = -ENODEV; + dev_err(cs35l41->dev, "Failed to add KControl: %s\n", fw_type_ctl.name); + goto err; + } + + dev_dbg(cs35l41->dev, "Added Control %s\n", fw_type_ctl.name); + + kctl2 = snd_ctl_new1(&fw_load_ctl, cs35l41); + if (!kctl2) { + ret = -ENOMEM; + goto err; + } + if (snd_ctl_add(cs35l41->codec->card, kctl2)) { + ret = -ENODEV; + dev_err(cs35l41->dev, "Failed to add KControl: %s, removing all controls\n", + fw_load_ctl.name); + goto err; + } + + dev_dbg(cs35l41->dev, "Added Control %s\n", fw_load_ctl.name); + +err: + kfree(fw_load_ctl.name); + kfree(fw_type_ctl.name); + + return ret; +} + static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); struct hda_component *comps = master_data; + int ret = 0; if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS) return -EINVAL; @@ -685,11 +860,16 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + cs35l41->firmware_type = HDA_CS_DSP_FW_SPK_PROT; + + cs35l41->request_fw_load = true; mutex_lock(&cs35l41->fw_mutex); if (cs35l41_smart_amp(cs35l41) < 0) dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); mutex_unlock(&cs35l41->fw_mutex); + ret = cs35l41_create_controls(cs35l41); + comps->playback_hook = cs35l41_hda_playback_hook; comps->suspend_hook = cs35l41_hda_suspend_hook; comps->resume_hook = cs35l41_hda_resume_hook; @@ -697,7 +877,7 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); - return 0; + return ret; } static void cs35l41_hda_unbind(struct device *dev, struct device *master, void *master_data) @@ -1208,6 +1388,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i if (ret) goto err; + INIT_WORK(&cs35l41->fw_load_work, cs35l41_fw_load_work); mutex_init(&cs35l41->fw_mutex); pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index 59a9461d0444..bdb35f3be68a 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -58,11 +58,17 @@ struct cs35l41_hda { unsigned volatile long irq_errors; const char *amp_name; const char *acpi_subsystem_id; + int firmware_type; int speaker_id; struct mutex fw_mutex; + struct work_struct fw_load_work; + struct regmap_irq_chip_data *irq_data; bool firmware_running; + bool request_fw_load; + bool fw_request_ongoing; bool halo_initialized; + bool playback_started; struct cs_dsp cs_dsp; }; From patchwork Wed Jun 22 07:46:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12890283 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A12B4C43334 for ; Wed, 22 Jun 2022 07:51:26 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id DD03221D1; Wed, 22 Jun 2022 09:50:34 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz DD03221D1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1655884284; bh=wQIO1H8fMSKSqu5ssYMtb8aeRSXOvIUZNUDRuZgZcgw=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=p6++wmerM9OMnSQAm2tx6tK+lQcyZ9bcZFm/cHijsyqKkV6y/LXPhRDr+SMk14WPS Ud4ly3S1DuDuAp+s97rAA9eIUpUdkgniA88h1XF6AtEd6OpgXkv64VgMNJ7xIYzvrT 3g8DP9IRa3CD1/Vh/chmgR8vsMqmE6eKFFcJa/CA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 45283F805AE; Wed, 22 Jun 2022 09:47:29 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id D75A9F8056F; Wed, 22 Jun 2022 09:47:20 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 524BBF8019B for ; Wed, 22 Jun 2022 09:47:05 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 524BBF8019B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="Nfq//OJT" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 25M5nide032367; Wed, 22 Jun 2022 02:47:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=i2GlN7h4TCNJX78uJ9xbCqKDkFCcSex86cITEC2VbPI=; b=Nfq//OJT/Xn1BDiymW0nJmJ4zAlM+cx4A0NO1zBfGFELk8TWG1ZOEv/AzzYwc3h8IUny wZzAtX7X494aOCcjGOEOStAZG537FJFIycCz66vo/QNDBXU4DTUUb0zw2Jin7My6d8HF +6oDzb0ZUwkElxTl7eE7muoZYAwkFYVMQNiHiChMSj6K2snwN4CBXBu6jTbIO7jQQ7Ni sbLdSypmcBFGSvuiulW5AviMueykYlPpwlALVy9khERy8eZP9l7ATZLAAaAmK8kObx6Z Dw/PMkQVnxYwPSjshUf3b3nBvtaOmVQ/m9WRXYrxzPPmoIGF7V3wWsfnS3tPVT48PcQ0 ew== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3gsc41cqh2-9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 22 Jun 2022 02:47:03 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Wed, 22 Jun 2022 08:47:00 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2375.28 via Frontend Transport; Wed, 22 Jun 2022 08:47:00 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.175]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 870A87C; Wed, 22 Jun 2022 07:47:00 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , Mark Brown Subject: [PATCH v7 14/14] ALSA: hda: cs35l41: Add module parameter to control firmware load Date: Wed, 22 Jun 2022 08:46:53 +0100 Message-ID: <20220622074653.179078-15-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> References: <20220622074653.179078-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: nFV1EIyYUTpIEkyYW9vKdkiupNmAxgj1 X-Proofpoint-ORIG-GUID: nFV1EIyYUTpIEkyYW9vKdkiupNmAxgj1 X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding By default, the driver will automatically load DSP firmware for the amps, if available. Adding this option allows the autoload to be optional, which allows for different configurations. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov --- sound/pci/hda/cs35l41_hda.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 3aa36c5ff972..4151ac5ab399 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,11 @@ #define CAL_DSP_CTL_TYPE 5 #define CAL_DSP_CTL_ALG 205 +static bool firmware_autostart = 1; +module_param(firmware_autostart, bool, 0444); +MODULE_PARM_DESC(firmware_autostart, "Allow automatic firmware download on boot" + "(0=Disable, 1=Enable) (default=1); "); + static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN @@ -862,11 +868,16 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas cs35l41->firmware_type = HDA_CS_DSP_FW_SPK_PROT; - cs35l41->request_fw_load = true; - mutex_lock(&cs35l41->fw_mutex); - if (cs35l41_smart_amp(cs35l41) < 0) - dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); - mutex_unlock(&cs35l41->fw_mutex); + if (firmware_autostart) { + dev_dbg(cs35l41->dev, "Firmware Autostart.\n"); + cs35l41->request_fw_load = true; + mutex_lock(&cs35l41->fw_mutex); + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); + mutex_unlock(&cs35l41->fw_mutex); + } else { + dev_dbg(cs35l41->dev, "Firmware Autostart is disabled.\n"); + } ret = cs35l41_create_controls(cs35l41);