Received: by 2002:a05:6602:18e:0:0:0:0 with SMTP id m14csp245240ioo; Fri, 20 May 2022 20:33:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyJKFionbWKmLgiYy2qWFlcRYOxmH3P0hCWEnliAM9Wa+mEY+7b9USREBcVy2HkGZJW4+Do X-Received: by 2002:a17:906:60cd:b0:6fd:d95c:3e34 with SMTP id f13-20020a17090660cd00b006fdd95c3e34mr11307949ejk.250.1653104025886; Fri, 20 May 2022 20:33:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1653104025; cv=none; d=google.com; s=arc-20160816; b=ziasuUiFhadHqlmEyxcMRsnddAjtBqQ3uTEE+mgKm1GQSWXdtQuDZCpYWJStmm3q7n je14tuuPhu3Aq9BRg+7XoXm3JRVu0En2NCaVUL5Mbv90HXb69X832GYGOeGJuxp4bKmz krS+ldMmOJEgm0FcgU8JyPmWN8bzxMxjZ5qICw4QTQMgP+GBeT80dvv8UUuRydoFLTh3 lyvqh7vXtRxKq1QMA+YAR+Jlivd/8dfyp4H3gHTBCoEwu1S4VZJ1UJlhL4LOq53FYo1n 6DLCmQYVUedCYvPe89Rkd3nM0aC60psTxD9Yjwau8OvSREUJi+a/ytCKtn+OIkguFbtJ YJPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=9mk8bGRr0pPSUQM7ozDYripyLIZEGJAyaNtwJgsEZqw=; b=FFHVP7yW7w8OIfivQrud5ax6F0aXC9I272TCOYJ96mKgQOx1OAWPpCW8v6vUcdo/g4 VfySSWYRTXlcJ6TEkmXXrtSycuuuq8WcZBZf2IlOvZdUNcAK0x2YDHZX0VrA5vx/Fu1i M06kFtt6Kd1u8dKd9dZ3hDu5PXX8FhLwwzTgywLW98jCBT+hr88k5GbNUL1LvRocwxsG NMD5TfBS3bNgBQtJ2uJ/wo8Rz3yurkLR/eFXwx681OMnPxKcdHxVVUp75gFJ6I8SUmaI QHhhUeeDBkliqMt1gtdh/NUUlBnaeZ3jxe7DvtBSb5XXOmeaKk29i9vwYVnZBt3v0lVg LoTw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cirrus.com header.s=PODMain02222019 header.b=fRVE7pj7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cirrus.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id cs11-20020a170906dc8b00b006f3c161e088si2514229ejc.544.2022.05.20.20.33.18; Fri, 20 May 2022 20:33:45 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@cirrus.com header.s=PODMain02222019 header.b=fRVE7pj7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cirrus.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243270AbiESRts (ORCPT + 99 others); Thu, 19 May 2022 13:49:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243183AbiESRsN (ORCPT ); Thu, 19 May 2022 13:48:13 -0400 Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67552B36CE for ; Thu, 19 May 2022 10:48:10 -0700 (PDT) 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 24J6k19B002261; Thu, 19 May 2022 12:47:53 -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=9mk8bGRr0pPSUQM7ozDYripyLIZEGJAyaNtwJgsEZqw=; b=fRVE7pj7p9x4lTzBUjmpWuDkbJoj7+je1YY1twvpRD0rKn1JEhj3pN5/HVIZMm6NzaD3 HxDHFGnMRWgViDCxJglzjH0XzMuINOs4IrYRvMLXu5U+1WZS4TN9uo6ogP1P3Pdk65fD AHFdVu2qwc3KXjcpOEnyTU65TImGqaJcbG6CplFGibxKIYnZbk9h67mSJKtI3YnaT39h kNJ1Bh/UEJRFM2jJtv6mbveRV1zdF8UkrxiJAH4R7dBFrNq7rTqPGaxEmHJSbCnFXQ89 PjSk7yTME7gqKh9RcCMqkzXPXondAtV5FFq3z2oA6a/js52RATO9L3W2L519IeV64PiD bA== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3g29u37ted-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Thu, 19 May 2022 12:47:53 -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.24; Thu, 19 May 2022 18:47:51 +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.24 via Frontend Transport; Thu, 19 May 2022 18:47:51 +0100 Received: from vitaly-Legion-7-16ACHg6.ad.cirrus.com (unknown [198.90.238.59]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 0B1E411D1; Thu, 19 May 2022 17:47:51 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai , "Mark Brown" CC: , , , Vitaly Rodionov Subject: [PATCH v3 04/17] ALSA: hda: cs35l41: Add initial DSP support and firmware loading Date: Thu, 19 May 2022 18:47:36 +0100 Message-ID: <20220519174749.15459-5-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220519174749.15459-1-vitalyr@opensource.cirrus.com> References: <20220519174749.15459-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-GUID: EY29qgKH2uahswkoMz8HN1M_R4BS8xYT X-Proofpoint-ORIG-GUID: EY29qgKH2uahswkoMz8HN1M_R4BS8xYT X-Proofpoint-Spam-Reason: safe X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 cusomtization for specific models. Signed-off-by: Vitaly Rodionov Signed-off-by: Vitaly Rodionov --- Changes since v2: - No change include/sound/cs35l41.h | 4 + sound/pci/hda/Kconfig | 4 + sound/pci/hda/cs35l41_hda.c | 238 +++++++++++++++++++++++++++++++++++- sound/pci/hda/cs35l41_hda.h | 12 ++ 4 files changed, 257 insertions(+), 1 deletion(-) diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 8972fa697622..8887087815a7 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..fe2ba03e602b 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,167 @@ 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.amp_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; + + cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, dsp); + dsp->client_ops = &client_ops; + + if (!cs35l41->halo_initialized) { + 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, "Loaded WMFW Firmware: %s\n", wmfw_filename); + if (coeff_filename) + dev_dbg(cs35l41->dev, "Loaded 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); + + if (wmfw_firmware) + release_firmware(wmfw_firmware); + if (coeff_firmware) + release_firmware(coeff_firmware); + kfree(wmfw_filename); + kfree(coeff_filename); + + return ret; +} + +static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) +{ + struct cs_dsp *dsp = &cs35l41->cs_dsp; + + cs_dsp_stop(dsp); + cs_dsp_power_down(dsp); + cs_dsp_remove(dsp); + cs35l41->firmware_running = false; + dev_dbg(cs35l41->dev, "Unloaded Firmware\n"); +} + /* 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) { @@ -55,7 +221,18 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) 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 +250,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: @@ -104,6 +288,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_remove_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 +350,9 @@ 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; + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); + return 0; } @@ -564,6 +796,9 @@ void cs35l41_hda_remove(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + if (cs35l41->firmware_running) + 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 +808,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..03c5f14631dd 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, @@ -40,6 +43,15 @@ struct cs35l41_hda { unsigned volatile long irq_errors; const char *amp_name; 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, -- 2.34.1