From nobody Mon May 25 04:34:28 2026 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA3213A874A for ; Mon, 18 May 2026 22:09:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142195; cv=none; b=ltfPYDTKY+VuMYa/kAIgvEi5U+dJeYYW+3rJVwxVGymFPen9hybHC8R3fpcBRWV/dgIcPXSafKcjvpbDD4IigfmF3V4FmqnhbyspihYz/pT7auS89clptEriS9GSLUQki8pjiVgvXF/4E2D7mJpL92GDvuV51qKzeccYzkznWhk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142195; c=relaxed/simple; bh=n+PAD86hX5fAbCBeVEAKy9jRtwKnRnkCMUzs5oPxyJw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X8DVzKOfRaQ/QIqNxZJOMY27IUe0n5q0G99rf0I81RKWUSQjdJvsfv14agElcJ2qeV0GpPAdO1vO6uVhe9rilIVynWsHSQqDEYc8h9PuNCnkS+2vuM8pWhgSW1xx4wk3qYJ7DDEs0PxHa699k3HvgV8i/Shrf1omIqlKCp+nI/U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool; spf=pass smtp.mailfrom=packett.cool; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b=Aw72sxJi; arc=none smtp.client-ip=91.218.175.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=packett.cool Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b="Aw72sxJi" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=packett.cool; s=key1; t=1779142189; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fCMxzHRZ4GceZB7pioSAng9MmhdiXjI9TjB7qTw99L4=; b=Aw72sxJiYOHYXBAPEvJNje4/e7dCtgeP4oHGI0Oti3fyQ+X7MKJWYSr67ZOHFQVtWiRTg/ Q06+TTSipjwH5M8GIDOcTYxJH/JA/Nz32bH4TmMrztTVNyaD2xFZnBir/SfG71dq81FZ6h ZvFtURREuhxsSu8vl+6zz3ht6puDL6KhYDoLkj2+Xig1Mt13Jhb8pzpDtBSEhRQ3l6il9v R7EefWNojFxPLqeR17AXLfc4dGnfMsoR05iqb6Xd0B7vUMaPPCO4tdmt0wz2YGunlx24bA DTvsSeN0KgtJeNlp3CZ2wh7zLPuEkR988r2wNaGSQoXE35607yNwxGuA0MFTzA== From: Val Packett To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Weidong Wang Cc: Val Packett , ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/7] ASoC: codecs: aw88261: support changing sample rate and bit width Date: Mon, 18 May 2026 18:44:30 -0300 Message-ID: <20260518220906.347958-2-val@packett.cool> In-Reply-To: <20260518220906.347958-1-val@packett.cool> References: <20260518220906.347958-1-val@packett.cool> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The aw88261 driver only worked with 32-bit 48kHz streams so far due to the lack of a proper PLL initialization sequence. Fix by selecting all the necessary PLL settings based on what was passed to us by the hw_params/set_fmt ops. This replaces the strange downstream routine that tries two divider modes in sequence. Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver") Signed-off-by: Val Packett Tested-by: Luca Weiss # qcm6490-fairphone-fp5 --- sound/soc/codecs/aw88261.c | 247 +++++++++++++++++++++++++++---------- sound/soc/codecs/aw88261.h | 116 ++++++++++++++++- 2 files changed, 299 insertions(+), 64 deletions(-) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index a6805d5405cd..2064e72b51af 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "aw88261.h" #include "aw88395/aw88395_data_type.h" #include "aw88395/aw88395_device.h" @@ -158,7 +159,7 @@ static int aw88261_dev_get_iis_status(struct aw_device = *aw_dev) return ret; } =20 -static int aw88261_dev_check_mode1_pll(struct aw_device *aw_dev) +static int aw88261_dev_check_pll(struct aw_device *aw_dev) { int ret, i; =20 @@ -175,71 +176,48 @@ static int aw88261_dev_check_mode1_pll(struct aw_devi= ce *aw_dev) return -EPERM; } =20 -static int aw88261_dev_check_mode2_pll(struct aw_device *aw_dev) -{ - unsigned int reg_val; - int ret, i; - - ret =3D regmap_read(aw_dev->regmap, AW88261_PLLCTRL1_REG, ®_val); - if (ret) - return ret; - - reg_val &=3D (~AW88261_CCO_MUX_MASK); - if (reg_val =3D=3D AW88261_CCO_MUX_DIVIDED_VALUE) { - dev_dbg(aw_dev->dev, "CCO_MUX is already divider"); - return -EPERM; - } - - /* change mode2 */ - ret =3D regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG, - ~AW88261_CCO_MUX_MASK, AW88261_CCO_MUX_DIVIDED_VALUE); - if (ret) - return ret; - - for (i =3D 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw88261_dev_get_iis_status(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "mode2 iis signal check error"); - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); - } else { - break; - } - } - - /* change mode1 */ - ret =3D regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG, - ~AW88261_CCO_MUX_MASK, AW88261_CCO_MUX_BYPASS_VALUE); - if (ret =3D=3D 0) { - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); - for (i =3D 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw88261_dev_check_mode1_pll(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); - } else { - break; - } - } - } - - return ret; -} - -static int aw88261_dev_check_syspll(struct aw_device *aw_dev) +static int aw88261_dev_configure_syspll(struct aw88261 *aw88261) { + struct aw_device *aw_dev =3D aw88261->aw_pa; int ret; =20 - ret =3D aw88261_dev_check_mode1_pll(aw_dev); - if (ret) { - dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); - ret =3D aw88261_dev_check_mode2_pll(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "mode2 check iis failed"); - return ret; - } - } + /* PLL divider must be used for 8/16/32 kHz modes */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG, + ~AW88261_CCO_MUX_MASK, aw88261->cco_mux_value); + if (ret) + return ret; =20 - return ret; + /* The word clock (WCK) defines the beginning of a frame */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL1_REG, + ~AW88261_I2SSR_MASK, aw88261->sr_value); + if (ret) + return ret; + + /* The bit clock (BCK) defines the length of a frame */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL1_REG, + ~AW88261_I2SBCK_MASK, aw88261->bck_value); + if (ret) + return ret; + + /* The logical frame size is the width of data for 1 slot */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL1_REG, + ~AW88261_I2SFS_MASK, aw88261->fs_value); + if (ret) + return ret; + + /* The I2S interface mode (Philips standard, LSB/MSB justified) */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL1_REG, + ~AW88261_I2SMD_MASK, aw88261->md_value); + if (ret) + return ret; + + /* The polarity of the bit clock (BCK) */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_BCKINV_MASK, aw88261->bck_inv_value); + if (ret) + return ret; + + return aw88261_dev_check_pll(aw_dev); } =20 static int aw88261_dev_check_sysst(struct aw_device *aw_dev) @@ -558,7 +536,7 @@ static int aw88261_dev_start(struct aw88261 *aw88261) aw88261_dev_pwd(aw_dev, false); usleep_range(AW88261_2000_US, AW88261_2000_US + 10); =20 - ret =3D aw88261_dev_check_syspll(aw_dev); + ret =3D aw88261_dev_configure_syspll(aw88261); if (ret) { dev_err(aw_dev->dev, "pll check failed cannot start"); goto pll_check_fail; @@ -712,6 +690,140 @@ static void aw88261_start(struct aw88261 *aw88261, bo= ol sync_start) AW88261_START_WORK_DELAY_MS); } =20 +static int aw88261_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_component *component =3D dai->component; + struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + aw88261->bck_inv_value =3D AW88261_BCKINV_NOT_INVERT_VALUE; + break; + case SND_SOC_DAIFMT_IB_NF: + aw88261->bck_inv_value =3D AW88261_BCKINV_INVERTED_VALUE; + break; + default: + dev_err(aw88261->aw_pa->dev, "unsupported invert mode 0x%x\n", + fmt & SND_SOC_DAIFMT_INV_MASK); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + aw88261->md_value =3D AW88261_I2SMD_PHILIPS_STANDARD_VALUE; + break; + case SND_SOC_DAIFMT_MSB: + aw88261->md_value =3D AW88261_I2SMD_MSB_JUSTIFIED_VALUE; + break; + case SND_SOC_DAIFMT_LSB: + aw88261->md_value =3D AW88261_I2SMD_LSB_JUSTIFIED_VALUE; + break; + default: + dev_err(aw88261->aw_pa->dev, "unsupported DAI format 0x%x\n", + fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return -EINVAL; + } + + return 0; +} + +static int aw88261_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component =3D dai->component; + struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); + + if (substream->stream =3D=3D SNDRV_PCM_STREAM_CAPTURE) + return 0; + + aw88261->cco_mux_value =3D AW88261_CCO_MUX_BYPASS_VALUE; + switch (params_rate(params)) { + case 8000: + aw88261->sr_value =3D AW88261_I2SSR_8KHZ_VALUE; + aw88261->cco_mux_value =3D AW88261_CCO_MUX_DIVIDED_VALUE; + break; + case 11025: + aw88261->sr_value =3D AW88261_I2SSR_11P025KHZ_VALUE; + break; + case 12000: + aw88261->sr_value =3D AW88261_I2SSR_12KHZ_VALUE; + break; + case 16000: + aw88261->sr_value =3D AW88261_I2SSR_16KHZ_VALUE; + aw88261->cco_mux_value =3D AW88261_CCO_MUX_DIVIDED_VALUE; + break; + case 22050: + aw88261->sr_value =3D AW88261_I2SSR_22P05KHZ_VALUE; + break; + case 24000: + aw88261->sr_value =3D AW88261_I2SSR_24KHZ_VALUE; + break; + case 32000: + aw88261->sr_value =3D AW88261_I2SSR_32KHZ_VALUE; + aw88261->cco_mux_value =3D AW88261_CCO_MUX_DIVIDED_VALUE; + break; + case 44100: + aw88261->sr_value =3D AW88261_I2SSR_44P1KHZ_VALUE; + break; + case 48000: + aw88261->sr_value =3D AW88261_I2SSR_48KHZ_VALUE; + break; + case 96000: + aw88261->sr_value =3D AW88261_I2SSR_96KHZ_VALUE; + break; + case 192000: + aw88261->sr_value =3D AW88261_I2SSR_192KHZ_VALUE; + break; + default: + dev_err(aw88261->aw_pa->dev, "unsupported sample rate %d\n", + params_rate(params)); + return -EINVAL; + } + + switch (params_width(params)) { + case 16: + aw88261->fs_value =3D AW88261_I2SFS_16_BITS_VALUE; + break; + case 20: + aw88261->fs_value =3D AW88261_I2SFS_20_BITS_VALUE; + break; + case 24: + aw88261->fs_value =3D AW88261_I2SFS_24_BITS_VALUE; + break; + case 32: + aw88261->fs_value =3D AW88261_I2SFS_32_BITS_VALUE; + break; + default: + dev_err(aw88261->aw_pa->dev, "unsupported bit width %d\n", + params_width(params)); + return -EINVAL; + } + + switch (params_physical_width(params)) { + case 16: + aw88261->bck_value =3D AW88261_I2SBCK_32FS_VALUE; + break; + case 24: + aw88261->bck_value =3D AW88261_I2SBCK_48FS_VALUE; + break; + case 32: + aw88261->bck_value =3D AW88261_I2SBCK_64FS_VALUE; + break; + default: + dev_err(aw88261->aw_pa->dev, "unsupported physical bit width %d\n", + params_physical_width(params)); + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dai_ops aw88261_dai_ops =3D { + .set_fmt =3D aw88261_set_fmt, + .hw_params =3D aw88261_hw_params, +}; + static struct snd_soc_dai_driver aw88261_dai[] =3D { { .name =3D "aw88261-aif", @@ -730,6 +842,7 @@ static struct snd_soc_dai_driver aw88261_dai[] =3D { .rates =3D AW88261_RATES, .formats =3D AW88261_FORMATS, }, + .ops =3D &aw88261_dai_ops, }, }; =20 @@ -1249,6 +1362,14 @@ static int aw88261_i2c_probe(struct i2c_client *i2c) if (!aw88261) return -ENOMEM; =20 + /* set defaults */ + aw88261->sr_value =3D AW88261_I2SSR_48KHZ_VALUE; + aw88261->cco_mux_value =3D AW88261_CCO_MUX_BYPASS_VALUE; + aw88261->fs_value =3D AW88261_I2SFS_24_BITS_VALUE; + aw88261->bck_value =3D AW88261_I2SBCK_64FS_VALUE; + aw88261->bck_inv_value =3D AW88261_BCKINV_NOT_INVERT_VALUE; + aw88261->md_value =3D AW88261_I2SMD_PHILIPS_STANDARD_VALUE; + mutex_init(&aw88261->lock); =20 i2c_set_clientdata(i2c, aw88261); diff --git a/sound/soc/codecs/aw88261.h b/sound/soc/codecs/aw88261.h index 1fee589608d6..3d7483d625a9 100644 --- a/sound/soc/codecs/aw88261.h +++ b/sound/soc/codecs/aw88261.h @@ -116,6 +116,19 @@ #define AW88261_VCALK_SHIFT (0) #define AW88261_VCALKL_SHIFT (0) =20 +#define AW88261_BCKINV_START_BIT (4) +#define AW88261_BCKINV_BITS_LEN (1) +#define AW88261_BCKINV_MASK \ + (~(((1<; Mon, 18 May 2026 22:09:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142196; cv=none; b=iYJzuXb395TDgpJUDzSG0tkk1U33CMfdrchH08M1vD5Sl7am1uGAYVEBAt5Kcq8pkwa3Obd1llAgHfw7dRUBAIEPjVv898IMK9et3e7joyEAazdTzHqOudyGFec/5zgRL+ayh3qiW4D4SQ7TYt8sxUoShOEJih47rNZVQtbFpt0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142196; c=relaxed/simple; bh=sNCgfx+dhN326YffZXqEHe8zh27tqbPObYhlgAzT5MA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q+TRTOe+xbS3xfo/w3x1B4CKdjWFcfKoCucY7nxVJlODvK7GQq/irt/gCThsyDd8tzPlxkJK9ZzsFNKryALwY12NZKQ9+xa1pXxoS/XVMOBpoM8+3lqZTfDSH72KDxHNf/DVjaZNecaBBDwuR4FcHp3j5IYfaR1IxBbnJZpoJ/k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool; spf=pass smtp.mailfrom=packett.cool; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b=INBtLlhv; arc=none smtp.client-ip=91.218.175.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=packett.cool Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b="INBtLlhv" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=packett.cool; s=key1; t=1779142193; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CeIhWRUdId3RlO6icWSNz/L/CL6oMAeYt9e4+Yiosw8=; b=INBtLlhvVr+GlvS8r1DSJ6RHrNnzz0xQmj9BNf8Obb8CUWsoV52Jbht82thFlNLRxiT2Rs EmK+zRtnRQx2DavLKx9rBNtlBRuqDT6XGlPMj6sWn8aVR3bBuG+TmKVQuo4+LYj8W0SeTW vfeY+6T/cnKFIfDWzPjUREaU6htDBMBiuH+x2t5CIBfpyFWFarMDttfG5dHIrW5SXdyrdJ UAtZfgU2HjTqgfSU972Tpjan8dC8WuCyvpLBtDX+75kqI9UL2IkDILV+RaC3xHYYUKY93L 4xxllGC8zrxLFjZIV0+jxMvtwbyQHF6LbEHJoxMM8UdE3yhkLywpBee1zb5NXg== From: Val Packett To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Val Packett , ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/7] ASoC: codecs: aw88261: add TDM support Date: Mon, 18 May 2026 18:44:31 -0300 Message-ID: <20260518220906.347958-3-val@packett.cool> In-Reply-To: <20260518220906.347958-1-val@packett.cool> References: <20260518220906.347958-1-val@packett.cool> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" This amp supports TDM mode, so implement the set_tdm_slot operation to let the SoC driver configure the TDM slot number, width, and masks. Signed-off-by: Val Packett Tested-by: Luca Weiss # qcm6490-fairphone-fp5 --- sound/soc/codecs/aw88261.c | 88 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/aw88261.h | 53 +++++++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index 2064e72b51af..7b0e778f5a25 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -10,6 +10,7 @@ =20 #include #include +#include #include #include #include @@ -181,6 +182,30 @@ static int aw88261_dev_configure_syspll(struct aw88261= *aw88261) struct aw_device *aw_dev =3D aw88261->aw_pa; int ret; =20 + /* Configure TDM slots (I2S is represented as no slots) */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL2_REG, + ~AW88261_SLOT_NUM_MASK, aw88261->slot_num_value); + if (ret) + return ret; + + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL2_REG, + ~AW88261_I2S_TX_SLOTVLD_MASK, + aw88261->tx_slotvld_mask); + if (ret) + return ret; + + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL2_REG, + ~AW88261_I2S_RXL_SLOTVLD_MASK, + aw88261->rxl_slotvld_mask); + if (ret) + return ret; + + ret =3D regmap_update_bits(aw_dev->regmap, AW88261_I2SCTRL2_REG, + ~AW88261_I2S_RXR_SLOTVLD_MASK, + aw88261->rxr_slotvld_mask); + if (ret) + return ret; + /* PLL divider must be used for 8/16/32 kHz modes */ ret =3D regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG, ~AW88261_CCO_MUX_MASK, aw88261->cco_mux_value); @@ -710,9 +735,11 @@ static int aw88261_set_fmt(struct snd_soc_dai *dai, un= signed int fmt) =20 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_DSP_A: aw88261->md_value =3D AW88261_I2SMD_PHILIPS_STANDARD_VALUE; break; case SND_SOC_DAIFMT_MSB: + case SND_SOC_DAIFMT_DSP_B: aw88261->md_value =3D AW88261_I2SMD_MSB_JUSTIFIED_VALUE; break; case SND_SOC_DAIFMT_LSB: @@ -819,9 +846,68 @@ static int aw88261_hw_params(struct snd_pcm_substream = *substream, return 0; } =20 +static int aw88261_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) +{ + struct snd_soc_component *component =3D dai->component; + struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); + int bit; + + switch (slots) { + case 0: + aw88261->slot_num_value =3D AW88261_SLOT_NUM_I2S_MODE_VALUE; + break; + case 1: + aw88261->slot_num_value =3D AW88261_SLOT_NUM_TDM1S_VALUE; + break; + case 2: + aw88261->slot_num_value =3D AW88261_SLOT_NUM_TDM2S_VALUE; + break; + case 4: + aw88261->slot_num_value =3D AW88261_SLOT_NUM_TDM4S_VALUE; + break; + case 6: + aw88261->slot_num_value =3D AW88261_SLOT_NUM_TDM6S_VALUE; + break; + case 8: + aw88261->slot_num_value =3D AW88261_SLOT_NUM_TDM8S_VALUE; + break; + case 16: + aw88261->slot_num_value =3D AW88261_SLOT_NUM_TDM16S_VALUE; + break; + default: + dev_err(aw88261->aw_pa->dev, "unsupported slot count %d\n", slots); + return -EINVAL; + } + + if (tx_mask !=3D 0) { + if ((bit =3D __ffs(tx_mask)) > 15) + return -EINVAL; + + aw88261->tx_slotvld_mask =3D bit << AW88261_I2S_TX_SLOTVLD_START_BIT; + } + + if (rx_mask !=3D 0) { + if ((bit =3D __ffs(rx_mask)) > 15) + return -EINVAL; + + aw88261->rxl_slotvld_mask =3D bit << AW88261_I2S_RXL_SLOTVLD_START_BIT; + } + + if ((rx_mask & ~BIT(bit)) !=3D 0) { + if ((bit =3D __ffs(rx_mask & ~BIT(bit))) > 15) + return -EINVAL; + + aw88261->rxr_slotvld_mask =3D bit << AW88261_I2S_RXR_SLOTVLD_START_BIT; + } + + return 0; +} + static const struct snd_soc_dai_ops aw88261_dai_ops =3D { .set_fmt =3D aw88261_set_fmt, .hw_params =3D aw88261_hw_params, + .set_tdm_slot =3D aw88261_set_tdm_slot, }; =20 static struct snd_soc_dai_driver aw88261_dai[] =3D { @@ -1363,12 +1449,14 @@ static int aw88261_i2c_probe(struct i2c_client *i2c) return -ENOMEM; =20 /* set defaults */ + aw88261->slot_num_value =3D AW88261_SLOT_NUM_I2S_MODE_VALUE; aw88261->sr_value =3D AW88261_I2SSR_48KHZ_VALUE; aw88261->cco_mux_value =3D AW88261_CCO_MUX_BYPASS_VALUE; aw88261->fs_value =3D AW88261_I2SFS_24_BITS_VALUE; aw88261->bck_value =3D AW88261_I2SBCK_64FS_VALUE; aw88261->bck_inv_value =3D AW88261_BCKINV_NOT_INVERT_VALUE; aw88261->md_value =3D AW88261_I2SMD_PHILIPS_STANDARD_VALUE; + aw88261->rxr_slotvld_mask =3D 1 << AW88261_I2S_RXR_SLOTVLD_START_BIT; =20 mutex_init(&aw88261->lock); =20 diff --git a/sound/soc/codecs/aw88261.h b/sound/soc/codecs/aw88261.h index 3d7483d625a9..02820795d434 100644 --- a/sound/soc/codecs/aw88261.h +++ b/sound/soc/codecs/aw88261.h @@ -368,6 +368,54 @@ #define AW88261_I2SSR_192KHZ_VALUE \ (AW88261_I2SSR_192KHZ << AW88261_I2SSR_START_BIT) =20 +#define AW88261_SLOT_NUM_START_BIT (12) +#define AW88261_SLOT_NUM_BITS_LEN (3) +#define AW88261_SLOT_NUM_MASK \ + (~(((1< To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Val Packett , ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/7] ASoC: codecs: aw88261: reduce log spam Date: Mon, 18 May 2026 18:44:32 -0300 Message-ID: <20260518220906.347958-4-val@packett.cool> In-Reply-To: <20260518220906.347958-1-val@packett.cool> References: <20260518220906.347958-1-val@packett.cool> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" This driver would create a wall of logspam during initialization due to e.g. the PLL not being ready while waiting for it to stabilize. Change intermediate dev_err() calls to dev_dbg() to reduce the noise. While here, log the detected chip ID when that check fails. Signed-off-by: Val Packett Tested-by: Luca Weiss # qcm6490-fairphone-fp5 --- sound/soc/codecs/aw88261.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index 7b0e778f5a25..d1fc3403cb5a 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -153,7 +153,7 @@ static int aw88261_dev_get_iis_status(struct aw_device = *aw_dev) if (ret) return ret; if ((reg_val & AW88261_BIT_PLL_CHECK) !=3D AW88261_BIT_PLL_CHECK) { - dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val); + dev_dbg(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val); return -EINVAL; } =20 @@ -167,7 +167,7 @@ static int aw88261_dev_check_pll(struct aw_device *aw_d= ev) for (i =3D 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) { ret =3D aw88261_dev_get_iis_status(aw_dev); if (ret) { - dev_err(aw_dev->dev, "mode1 iis signal check error"); + dev_dbg(aw_dev->dev, "mode1 iis signal check error"); usleep_range(AW88261_2000_US, AW88261_2000_US + 10); } else { return ret; @@ -259,7 +259,7 @@ static int aw88261_dev_check_sysst(struct aw_device *aw= _dev) check_val =3D reg_val & (~AW88261_BIT_SYSST_CHECK_MASK) & AW88261_BIT_SYSST_CHECK; if (check_val !=3D AW88261_BIT_SYSST_CHECK) { - dev_err(aw_dev->dev, "check sysst fail, reg_val=3D0x%04x, check:0x%x", + dev_dbg(aw_dev->dev, "check sysst fail, reg_val=3D0x%04x, check:0x%x", reg_val, AW88261_BIT_SYSST_CHECK); usleep_range(AW88261_2000_US, AW88261_2000_US + 10); } else { @@ -553,7 +553,7 @@ static int aw88261_dev_start(struct aw88261 *aw88261) int ret; =20 if (aw_dev->status =3D=3D AW88261_DEV_PW_ON) { - dev_info(aw_dev->dev, "already power on"); + dev_dbg(aw_dev->dev, "already power on"); return 0; } =20 @@ -563,7 +563,7 @@ static int aw88261_dev_start(struct aw88261 *aw88261) =20 ret =3D aw88261_dev_configure_syspll(aw88261); if (ret) { - dev_err(aw_dev->dev, "pll check failed cannot start"); + dev_dbg(aw_dev->dev, "pll check failed"); goto pll_check_fail; } =20 @@ -574,7 +574,7 @@ static int aw88261_dev_start(struct aw88261 *aw88261) /* check i2s status */ ret =3D aw88261_dev_check_sysst(aw_dev); if (ret) { - dev_err(aw_dev->dev, "sysst check failed"); + dev_dbg(aw_dev->dev, "sysst check failed"); goto sysst_check_fail; } =20 @@ -675,18 +675,22 @@ static void aw88261_start_pa(struct aw88261 *aw88261) for (i =3D 0; i < AW88261_START_RETRIES; i++) { ret =3D aw88261_reg_update(aw88261, aw88261->phase_sync); if (ret) { - dev_err(aw88261->aw_pa->dev, "fw update failed, cnt:%d\n", i); + dev_dbg(aw88261->aw_pa->dev, + "aw88261_reg_update failed, cnt:%d, ret:%d\n", i, ret); continue; } ret =3D aw88261_dev_start(aw88261); if (ret) { - dev_err(aw88261->aw_pa->dev, "aw88261 device start failed. retry =3D %d= ", i); + dev_dbg(aw88261->aw_pa->dev, + "aw88261_dev_start failed, cnt:%d, ret:%d\n", i, ret); continue; } else { - dev_info(aw88261->aw_pa->dev, "start success\n"); + dev_dbg(aw88261->aw_pa->dev, "start success\n"); break; } } + if (ret !=3D 0) + dev_err(aw88261->aw_pa->dev, "start failure (%d)\n", ret); } =20 static void aw88261_startup_work(struct work_struct *work) @@ -1407,7 +1411,7 @@ static int aw88261_init(struct aw88261 *aw88261, stru= ct i2c_client *i2c, struct return ret; } if (chip_id !=3D AW88261_CHIP_ID) { - dev_err(&i2c->dev, "unsupported device"); + dev_err(&i2c->dev, "unsupported device id =3D %x", chip_id); return -ENXIO; } =20 --=20 2.53.0 From nobody Mon May 25 04:34:28 2026 Received: from out-183.mta0.migadu.com (out-183.mta0.migadu.com [91.218.175.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 654453A9017 for ; Mon, 18 May 2026 22:10:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142204; cv=none; b=MsRUL+hVKrBMzjY3/lhcxpSNnAmMYuLxmDUXiNv4WlRVP0n1ys0Xn7BQGde7hnJEKwQ915B2P14XORWLibIYRfDxQRrY8pZVqmNP4D9FFSnNcXRzW5PqF19VhVUSwfZf2vfX+bymsFyIoUf8aGrZZhPAxwvZgEAMUvBzFS8D7QU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142204; c=relaxed/simple; bh=Gng09ZVjxIUQtjT6CwVjWQrKmKvtPgnvkwMmSCuU1R4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dOMjGF1bHPWNLTsIoF81T6fZSHQcQq/+lCD7MbpRXDYX6GCFgtdh7JHzkKne2tEOItEsCA2z5IncWXVFwnz0e1oaKhdvmJ4LDH1BMlE7FdV5tKn0SDsk1mnf6gBQexWAspFG28Bo00g+3LX56XtniocbJZqxxtEgDj4JXZVl0EQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool; spf=pass smtp.mailfrom=packett.cool; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b=qZ1ILxFu; arc=none smtp.client-ip=91.218.175.183 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=packett.cool Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b="qZ1ILxFu" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=packett.cool; s=key1; t=1779142200; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jAidUZ+Fxpswpyf14V25vo5EL9uh0VjzUWu2r2SDXxI=; b=qZ1ILxFuBhwyaxcriFNaAtsLHgFTknY8KVjQEwn3T6KqRFzJj4ChKe6setmQc2xIvS0uw9 xnUmJ7wIzmX7bpIl62crTwRGtH/0ZPmixpB/aD0seIxvttQFJLXc9MFr9UMyl8k08tXWul LnxBgKR08cLkVDHUB43nQr7gZot/Due9krx7hiAqlqsvQPHrlP5s68vrrOwxRBN9YQdURE audtdxaTGCETdzrnVarC1e68UUMmwYPKcQVgfCvLUn2DsaOuc16r8NtqWihwf5XtVT1qn/ Cg1Pd7ndPA6OMmht+5xERW3pPceOoK2lG0yrQ8oX+PfZcq59JYpQ7JOKUrf2+g== From: Val Packett To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Val Packett , ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/7] ASoC: codecs: aw88261: remove fade in/out on start/stop Date: Mon, 18 May 2026 18:44:33 -0300 Message-ID: <20260518220906.347958-5-val@packett.cool> In-Reply-To: <20260518220906.347958-1-val@packett.cool> References: <20260518220906.347958-1-val@packett.cool> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" This "feature" was copied from downstream, but it does not belong in the kernel at all. Remove it to simplify the driver. Signed-off-by: Val Packett Tested-by: Luca Weiss # qcm6490-fairphone-fp5 --- sound/soc/codecs/aw88261.c | 158 +------------------------------------ sound/soc/codecs/aw88261.h | 3 - 2 files changed, 2 insertions(+), 159 deletions(-) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index d1fc3403cb5a..ba2a0b0fc296 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -45,50 +45,6 @@ static void aw88261_dev_set_volume(struct aw_device *aw_= dev, unsigned int value) regmap_write(aw_dev->regmap, AW88261_SYSCTRL2_REG, real_value); } =20 -static void aw88261_dev_fade_in(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_in_vol =3D desc->ctl_volume; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_in_time =3D=3D 0) { - aw88261_dev_set_volume(aw_dev, fade_in_vol); - return; - } - - for (i =3D AW88261_MUTE_VOL; i >=3D fade_in_vol; i -=3D fade_step) { - aw88261_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_in_time, - aw_dev->fade_in_time + 10); - } - - if (i !=3D fade_in_vol) - aw88261_dev_set_volume(aw_dev, fade_in_vol); -} - -static void aw88261_dev_fade_out(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_out_time =3D=3D 0) { - aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL); - return; - } - - for (i =3D desc->ctl_volume; i <=3D AW88261_MUTE_VOL; i +=3D fade_step) { - aw88261_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } - - if (i !=3D AW88261_MUTE_VOL) { - aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } -} - static void aw88261_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) { if (flag) @@ -122,13 +78,13 @@ static void aw88261_dev_amppd(struct aw_device *aw_dev= , bool amppd) static void aw88261_dev_mute(struct aw_device *aw_dev, bool is_mute) { if (is_mute) { - aw88261_dev_fade_out(aw_dev); + aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL); regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, ~AW88261_HMUTE_MASK, AW88261_HMUTE_ENABLE_VALUE); } else { regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, ~AW88261_HMUTE_MASK, AW88261_HMUTE_DISABLE_VALUE); - aw88261_dev_fade_in(aw_dev); + aw88261_dev_set_volume(aw_dev, aw_dev->volume_desc.ctl_volume); } } =20 @@ -936,75 +892,6 @@ static struct snd_soc_dai_driver aw88261_dai[] =3D { }, }; =20 -static int aw88261_get_fade_in_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); - struct aw_device *aw_dev =3D aw88261->aw_pa; - - ucontrol->value.integer.value[0] =3D aw_dev->fade_in_time; - - return 0; -} - -static int aw88261_set_fade_in_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - struct aw_device *aw_dev =3D aw88261->aw_pa; - int time; - - time =3D ucontrol->value.integer.value[0]; - - if (time < mc->min || time > mc->max) - return -EINVAL; - - if (time !=3D aw_dev->fade_in_time) { - aw_dev->fade_in_time =3D time; - return 1; - } - - return 0; -} - -static int aw88261_get_fade_out_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); - struct aw_device *aw_dev =3D aw88261->aw_pa; - - ucontrol->value.integer.value[0] =3D aw_dev->fade_out_time; - - return 0; -} - -static int aw88261_set_fade_out_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_kcontrol_chip(kcontrol); - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - struct aw_device *aw_dev =3D aw88261->aw_pa; - int time; - - time =3D ucontrol->value.integer.value[0]; - if (time < mc->min || time > mc->max) - return -EINVAL; - - if (time !=3D aw_dev->fade_out_time) { - aw_dev->fade_out_time =3D time; - return 1; - } - - return 0; -} - static int aw88261_dev_set_profile_index(struct aw_device *aw_dev, int ind= ex) { /* check the index whether is valid */ @@ -1128,48 +1015,10 @@ static int aw88261_volume_set(struct snd_kcontrol *= kcontrol, return 0; } =20 -static int aw88261_get_fade_step(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_kcontrol_chip(kcontrol); - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(codec); - - ucontrol->value.integer.value[0] =3D aw88261->aw_pa->fade_step; - - return 0; -} - -static int aw88261_set_fade_step(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_kcontrol_chip(kcontrol); - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(codec); - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - int value; - - value =3D ucontrol->value.integer.value[0]; - if (value < mc->min || value > mc->max) - return -EINVAL; - - if (aw88261->aw_pa->fade_step !=3D value) { - aw88261->aw_pa->fade_step =3D value; - return 1; - } - - return 0; -} - static const struct snd_kcontrol_new aw88261_controls[] =3D { SOC_SINGLE_EXT("PCM Playback Volume", AW88261_SYSCTRL2_REG, 6, AW88261_MUTE_VOL, 0, aw88261_volume_get, aw88261_volume_set), - SOC_SINGLE_EXT("Fade Step", 0, 0, AW88261_MUTE_VOL, 0, - aw88261_get_fade_step, aw88261_set_fade_step), - SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN, - aw88261_get_fade_in_time, aw88261_set_fade_in_time), - SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MI= N, - aw88261_get_fade_out_time, aw88261_set_fade_out_time), AW88261_PROFILE_EXT("Profile Set", aw88261_profile_info, aw88261_profile_get, aw88261_profile_set), }; @@ -1260,8 +1109,6 @@ static int aw88261_dev_init(struct aw88261 *aw88261, = struct aw_container *aw_cfg if (ret) return ret; =20 - aw_dev->fade_in_time =3D AW88261_500_US; - aw_dev->fade_out_time =3D AW88261_500_US; aw_dev->prof_cur =3D AW88261_INIT_PROFILE; aw_dev->prof_index =3D AW88261_INIT_PROFILE; =20 @@ -1432,7 +1279,6 @@ static int aw88261_init(struct aw88261 *aw88261, stru= ct i2c_client *i2c, struct aw_dev->prof_info.prof_type =3D AW88395_DEV_NONE_TYPE_ID; aw_dev->channel =3D 0; aw_dev->fw_status =3D AW88261_DEV_FW_FAILED; - aw_dev->fade_step =3D AW88261_VOLUME_STEP_DB; aw_dev->volume_desc.ctl_volume =3D AW88261_VOL_DEFAULT_VALUE; aw_dev->volume_desc.mute_volume =3D AW88261_MUTE_VOL; aw88261_parse_channel_dt(aw88261); diff --git a/sound/soc/codecs/aw88261.h b/sound/soc/codecs/aw88261.h index 02820795d434..12c98f01fcfe 100644 --- a/sound/soc/codecs/aw88261.h +++ b/sound/soc/codecs/aw88261.h @@ -531,9 +531,6 @@ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) =20 -#define FADE_TIME_MAX 100000 -#define FADE_TIME_MIN 0 - #define AW88261_DEV_DEFAULT_CH (0) #define AW88261_ACF_FILE "aw88261_acf.bin" #define AW88261_DEV_SYSST_CHECK_MAX (10) --=20 2.53.0 From nobody Mon May 25 04:34:28 2026 Received: from out-184.mta0.migadu.com (out-184.mta0.migadu.com [91.218.175.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C7363A8753 for ; Mon, 18 May 2026 22:10:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142207; cv=none; b=nKX3Q6Zbt1QP9yzR8oKk/z+xLAGedco0Xm54beTSYPmO6h1kYLx3jdliaA8fjohce9rvuyc2l5hK1kNf9Jta/l5gn/xLmEzfVJIak6H7q6xSLV9OJTYOBpD7wyMzwdMq4Jc3gcB3lGdC5K0Y/BeZ5C1oNKPtkquCZa6hcx9R8tM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142207; c=relaxed/simple; bh=URmp26tKBGoiicxLrMXpHPTiImn6hJvImXigNcRJes4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iI9VOn97RRbB7PgVUXB6M3lyKjYPpYQZLebGVALGhP8qmsmWdAD4VISkDHrmmKplO4N14qZ/8osE00yn3SOEVgLv7NJJnvIV2O1boPlVcXlokIwLfLUdMLsxC44/aRu5BcHQsWYWy/tEejVdmFw92P2NfOxdN2Tkn6iHzgVgCPc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool; spf=pass smtp.mailfrom=packett.cool; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b=ZrJAXo9w; arc=none smtp.client-ip=91.218.175.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=packett.cool Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b="ZrJAXo9w" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=packett.cool; s=key1; t=1779142204; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3K4qR9C35aVhEtDaP0TWG4lhSCAS1YIunpYZOMyKOHw=; b=ZrJAXo9wIvPAuFTTtDxsedeif5y655fPDRNNuTt3FkNRwR+tn3Yx8YVQCqG/WBhcQV+BOz 5UFv84kHepcYehZ5RIjVKIK5KF8I6E5eheJtZRMN8IiybiBzphHkcNRCJ4qSND/98+/+cc 9kzMsVWX+yWuvAfmuc+ojs4RN5nKaxlhlAzpSo7YQVVqgCDeX3TTL8kol8HYYEDZ6PgKfv cbCl2fI+2r59s+41wt0Yiyd57F9ku/wlvOdtlr7rfxIgS8JyKeiXVacIxgX1OBFOT2ztM5 Rmj7lIWP0R/iTANwWHMBtLKWSZylLKHSTYvotwtW5ZNe7CBiL9vMNNtWgLSITQ== From: Val Packett To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Val Packett , ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/7] ASoC: codecs: aw88261: remove async start Date: Mon, 18 May 2026 18:44:34 -0300 Message-ID: <20260518220906.347958-6-val@packett.cool> In-Reply-To: <20260518220906.347958-1-val@packett.cool> References: <20260518220906.347958-1-val@packett.cool> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Codec drivers are not supposed to do anything like this. The result was that the first second or so of playback was essentially inaudible, and very short alert sounds could be missed entirely. Let's not do this. Signed-off-by: Val Packett Tested-by: Luca Weiss # qcm6490-fairphone-fp5 --- sound/soc/codecs/aw88261.c | 33 ++++----------------------------- sound/soc/codecs/aw88261.h | 6 ------ 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index ba2a0b0fc296..e0644fb445e5 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -649,17 +649,7 @@ static void aw88261_start_pa(struct aw88261 *aw88261) dev_err(aw88261->aw_pa->dev, "start failure (%d)\n", ret); } =20 -static void aw88261_startup_work(struct work_struct *work) -{ - struct aw88261 *aw88261 =3D - container_of(work, struct aw88261, start_work.work); - - mutex_lock(&aw88261->lock); - aw88261_start_pa(aw88261); - mutex_unlock(&aw88261->lock); -} - -static void aw88261_start(struct aw88261 *aw88261, bool sync_start) +static void aw88261_start(struct aw88261 *aw88261) { if (aw88261->aw_pa->fw_status !=3D AW88261_DEV_FW_OK) return; @@ -667,12 +657,7 @@ static void aw88261_start(struct aw88261 *aw88261, boo= l sync_start) if (aw88261->aw_pa->status =3D=3D AW88261_DEV_PW_ON) return; =20 - if (sync_start =3D=3D AW88261_SYNC_START) - aw88261_start_pa(aw88261); - else - queue_delayed_work(system_dfl_wq, - &aw88261->start_work, - AW88261_START_WORK_DELAY_MS); + aw88261_start_pa(aw88261); } =20 static int aw88261_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) @@ -970,7 +955,7 @@ static int aw88261_profile_set(struct snd_kcontrol *kco= ntrol, =20 if (aw88261->aw_pa->status) { aw88261_dev_stop(aw88261->aw_pa); - aw88261_start(aw88261, AW88261_SYNC_START); + aw88261_start(aw88261); } =20 mutex_unlock(&aw88261->lock); @@ -1032,7 +1017,7 @@ static int aw88261_playback_event(struct snd_soc_dapm= _widget *w, mutex_lock(&aw88261->lock); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aw88261_start(aw88261, AW88261_ASYNC_START); + aw88261_start(aw88261); break; case SND_SOC_DAPM_POST_PMD: aw88261_dev_stop(aw88261->aw_pa); @@ -1192,8 +1177,6 @@ static int aw88261_codec_probe(struct snd_soc_compone= nt *component) struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); int ret; =20 - INIT_DELAYED_WORK(&aw88261->start_work, aw88261_startup_work); - ret =3D aw88261_request_firmware_file(aw88261); if (ret) return dev_err_probe(aw88261->aw_pa->dev, ret, @@ -1217,16 +1200,8 @@ static int aw88261_codec_probe(struct snd_soc_compon= ent *component) return ret; } =20 -static void aw88261_codec_remove(struct snd_soc_component *aw_codec) -{ - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(aw_codec); - - cancel_delayed_work_sync(&aw88261->start_work); -} - static const struct snd_soc_component_driver soc_codec_dev_aw88261 =3D { .probe =3D aw88261_codec_probe, - .remove =3D aw88261_codec_remove, }; =20 static void aw88261_parse_channel_dt(struct aw88261 *aw88261) diff --git a/sound/soc/codecs/aw88261.h b/sound/soc/codecs/aw88261.h index 12c98f01fcfe..1b1beba6a26b 100644 --- a/sound/soc/codecs/aw88261.h +++ b/sound/soc/codecs/aw88261.h @@ -555,11 +555,6 @@ .put =3D profile_set, \ } =20 -enum { - AW88261_SYNC_START =3D 0, - AW88261_ASYNC_START, -}; - enum aw88261_id { AW88261_CHIP_ID =3D 0x2113, }; @@ -594,7 +589,6 @@ struct aw88261 { struct aw_device *aw_pa; struct mutex lock; struct gpio_desc *reset_gpio; - struct delayed_work start_work; struct regmap *regmap; struct aw_container *aw_cfg; =20 --=20 2.53.0 From nobody Mon May 25 04:34:28 2026 Received: from out-180.mta0.migadu.com (out-180.mta0.migadu.com [91.218.175.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B9553ACA40 for ; Mon, 18 May 2026 22:10:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142211; cv=none; b=DLMNazeJmhKkIeBZ45Q/s4nQILTd+WeI9ksnCP1Y+uSFjufLNPs4CgJ4kCElGn4ciKqqtC74u1VOZy0Fe35f5YxWNsG2HAYbbvrz1bzJl7Ip/K+MFuk/PwamczqB5kTd5bdNySPpC3AuSWpwuwU7PY1WBfQnewPOdHY+tL8pVU4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142211; c=relaxed/simple; bh=Hn2bJkM+wPBqb/3c+mJmhDMQaXMTitpPKGLZeUwp884=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mPbsrERpdIRl6X6AIP1lWGRsGZ8ByNqvDV8isDlOvhChZ4wG8GkgaZAZwOrsU4MOHVZspInjyv9xucuUrSz+4qWZUm7bdrDO9ITzFxGQfERbiPyisR3tDaXVXkhAPKLiK+TwLMnrtwwXUf62V3E7vM8GvOvHPvBBeGIURQDKWeI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool; spf=pass smtp.mailfrom=packett.cool; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b=XPKUI0wh; arc=none smtp.client-ip=91.218.175.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=packett.cool Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b="XPKUI0wh" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=packett.cool; s=key1; t=1779142208; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cA+m07xuXA8ONwm95/Iao29FiNKsZwHD5SiIzqacaxw=; b=XPKUI0wh3i4+XWpltC981mbVF6N9cubBJ2EXaXNpwgBJ0ACIQJGKQ4qV1+JXDwq72mjc3F DKpRkXc1GOVAU2JJdop4Wdsgd+qZwjvEGM2+zwfpPxFUgsi0/LDtmo7v1s3nqAfx5QFVIL 2o9YmFuoRpJNBbPEMR3KhsZca5g97UFUeB920HFr0GkfY7HkGvZVgo4jIYDbx/IWM4I1q6 CsR+XCakugx/yXb8hJ0y7ezA4WcNdRp9jdKQbXYHLfB/VW6NPNZoYsT6WmKdw3kWO8V19W AJypAAPwFMcPt6vmuUSY/+Fg1tBD36Kro7+5rK6DlOOh8SWOly01yAC8Vx0NhA== From: Val Packett To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Weidong Wang Cc: Val Packett , ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 6/7] ASoC: codecs: aw88261: fix incorrect masks for boost regs Date: Mon, 18 May 2026 18:44:35 -0300 Message-ID: <20260518220906.347958-7-val@packett.cool> In-Reply-To: <20260518220906.347958-1-val@packett.cool> References: <20260518220906.347958-1-val@packett.cool> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The boost-related register fields used in aw88261_reg_force_set use the exact same definitions as the rest of the fields, where the mask must be inverted when passing it to regmap_update_bits, but they weren't inverted here. Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver") Signed-off-by: Val Packett Tested-by: Luca Weiss # qcm6490-fairphone-fp5 --- sound/soc/codecs/aw88261.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index e0644fb445e5..adc728e45f57 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -243,22 +243,22 @@ static void aw88261_reg_force_set(struct aw88261 *aw8= 8261) if (aw88261->frcset_en =3D=3D AW88261_FRCSET_ENABLE) { /* set FORCE_PWM */ regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL3_REG, - AW88261_FORCE_PWM_MASK, AW88261_FORCE_PWM_FORCEMINUS_PWM_VALUE); + ~AW88261_FORCE_PWM_MASK, AW88261_FORCE_PWM_FORCEMINUS_PWM_VALUE); /* set BOOST_OS_WIDTH */ regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL5_REG, - AW88261_BST_OS_WIDTH_MASK, AW88261_BST_OS_WIDTH_50NS_VALUE); + ~AW88261_BST_OS_WIDTH_MASK, AW88261_BST_OS_WIDTH_50NS_VALUE); /* set BURST_LOOPR */ regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL6_REG, - AW88261_BST_LOOPR_MASK, AW88261_BST_LOOPR_340K_VALUE); + ~AW88261_BST_LOOPR_MASK, AW88261_BST_LOOPR_340K_VALUE); /* set RSQN_DLY */ regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL7_REG, - AW88261_RSQN_DLY_MASK, AW88261_RSQN_DLY_35NS_VALUE); + ~AW88261_RSQN_DLY_MASK, AW88261_RSQN_DLY_35NS_VALUE); /* set BURST_SSMODE */ regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL8_REG, - AW88261_BURST_SSMODE_MASK, AW88261_BURST_SSMODE_FAST_VALUE); + ~AW88261_BURST_SSMODE_MASK, AW88261_BURST_SSMODE_FAST_VALUE); /* set BST_BURST */ regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL9_REG, - AW88261_BST_BURST_MASK, AW88261_BST_BURST_30MA_VALUE); + ~AW88261_BST_BURST_MASK, AW88261_BST_BURST_30MA_VALUE); } else { dev_dbg(aw88261->aw_pa->dev, "needn't set reg value"); } --=20 2.53.0 From nobody Mon May 25 04:34:28 2026 Received: from out-184.mta0.migadu.com (out-184.mta0.migadu.com [91.218.175.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F49E3AD513 for ; Mon, 18 May 2026 22:10:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142215; cv=none; b=BJ6eRSLIQFXkD/1/FMccrx6lfaDgal2e3wVW/khH013IYfZDetQnkP7Gje+QhPPe7ciWgdi/aZ3KjvAUnG0s+IQyLJG/wGMC2ozXqmysm/kUuzNnw9slLJRGTT9AoKQ8j5ZRcSMh4w3IYmR8pkKIGXR9FI3BY9gtHwfmcl/EtF0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779142215; c=relaxed/simple; bh=lv9N+7Z8VW0vAE7era4BadpcmJzvEyBHEEfXSW/r0IY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N8NHbzFicwk7ebqlEc73j0ZiOWQUT99d+Kw3xDRqMi5VKkTScPNDaihEue36m47ojmUgOFZkDJ6OQRLeFO8WVp2U/AWMhHHi9VYcIre6u96Umee3tVO7PPsaGHz/JxQcya6MGa9pKlBi3EsgirdlpwWuY8L7kpTgA0ITtlGHwyA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool; spf=pass smtp.mailfrom=packett.cool; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b=N5j8KoYd; arc=none smtp.client-ip=91.218.175.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=packett.cool Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=packett.cool Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=packett.cool header.i=@packett.cool header.b="N5j8KoYd" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=packett.cool; s=key1; t=1779142212; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hZHMcEa/nUuSwW8bqcx2odanePCj/SZB7U7QS52W71Q=; b=N5j8KoYdQs7yFYqs/+9KrPhxklbOPiN711flZIJB5vYfg64dagekhk3r5DhnJS6ZkJqtyC ga3bXk9KcRmvZChAhATIGbr6b6bL6HXZpeWNDa6JIgZWU0KzVzKFAAR/pH3XlR8vSuEuhs 4c+V/mIC4A1Klgd/jJd5K7ei/YsTZXisSIcXDnkIHDKXP4nOwr9KIX7GlG8LMlGrFjILqr UgJ2k7xtuPdzpkej0WXQt1UBWorCv+Vj8C70+QLT9iIJI9p6qbOXvJEy1cVjAzGsrriXmf OEdj/mMsKzL6CNOSFjvdG8qvgwQ9bp2SqEP9P8O4p1PLXxUtdJt9s2mAm6Bkrg== From: Val Packett To: Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Weidong Wang Cc: Val Packett , ~postmarketos/upstreaming@lists.sr.ht, phone-devel@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 7/7] ASoC: codecs: aw88261: make volume control usable Date: Mon, 18 May 2026 18:44:36 -0300 Message-ID: <20260518220906.347958-8-val@packett.cool> In-Reply-To: <20260518220906.347958-1-val@packett.cool> References: <20260518220906.347958-1-val@packett.cool> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" - Invert the value to match userspace expectations (in the hardware, positive numbers represent negative dB attenuation) - Provide TLV metadata for the dB scale (and divide the raw values by 2 as the excessive precision used by HW is not representable in TLV) - Do not unnecessarily reset the volume while switching profiles - Simplify aw88261_dev_set_volume using regmap_update_bits - Do not add the initial volume from the profile to the requested volume as that would throw off the dB mapping (if a lower max limit is desired, it can be set in the UCM profile in userspace) With this change, it's actually possible to use this hardware volume control as PlaybackVolume in an ALSA UCM profile. Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver") Signed-off-by: Val Packett Tested-by: Luca Weiss # qcm6490-fairphone-fp5 --- sound/soc/codecs/aw88261.c | 52 +++++++++++++++----------------------- sound/soc/codecs/aw88261.h | 1 - 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index adc728e45f57..0e6b2dfe5db9 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "aw88261.h" #include "aw88395/aw88395_data_type.h" #include "aw88395/aw88395_device.h" @@ -29,20 +30,10 @@ static const struct regmap_config aw88261_remap_config = =3D { =20 static void aw88261_dev_set_volume(struct aw_device *aw_dev, unsigned int = value) { - struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; - unsigned int real_value, volume; - unsigned int reg_value; + unsigned int volume =3D min(value, (unsigned int)AW88261_MUTE_VOL); =20 - volume =3D min((value + vol_desc->init_volume), (unsigned int)AW88261_MUT= E_VOL); - real_value =3D DB_TO_REG_VAL(volume); - - regmap_read(aw_dev->regmap, AW88261_SYSCTRL2_REG, ®_value); - - real_value =3D (real_value | (reg_value & AW88261_VOL_START_MASK)); - - dev_dbg(aw_dev->dev, "value 0x%x , real_value:0x%x", value, real_value); - - regmap_write(aw_dev->regmap, AW88261_SYSCTRL2_REG, real_value); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL2_REG, + ~AW88261_VOL_MASK, DB_TO_REG_VAL(volume)); } =20 static void aw88261_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) @@ -424,17 +415,7 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88= 261, break; } =20 - ret =3D aw88261_dev_set_vcalb(aw_dev); - if (ret) - return ret; - - if (aw_dev->prof_cur !=3D aw_dev->prof_index) - vol_desc->ctl_volume =3D 0; - - /* keep min volume */ - aw88261_dev_set_volume(aw_dev, vol_desc->mute_volume); - - return ret; + return aw88261_dev_set_vcalb(aw_dev); } =20 static int aw88261_dev_get_prof_name(struct aw_device *aw_dev, int index, = char **prof_name) @@ -970,7 +951,8 @@ static int aw88261_volume_get(struct snd_kcontrol *kcon= trol, struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(codec); struct aw_volume_desc *vol_desc =3D &aw88261->aw_pa->volume_desc; =20 - ucontrol->value.integer.value[0] =3D vol_desc->ctl_volume; + ucontrol->value.integer.value[0] =3D + (AW88261_MUTE_VOL - vol_desc->ctl_volume) / 2; =20 return 0; } @@ -983,13 +965,13 @@ static int aw88261_volume_set(struct snd_kcontrol *kc= ontrol, struct aw_volume_desc *vol_desc =3D &aw88261->aw_pa->volume_desc; struct soc_mixer_control *mc =3D (struct soc_mixer_control *)kcontrol->private_value; - int value; - - value =3D ucontrol->value.integer.value[0]; + int value =3D ucontrol->value.integer.value[0]; =20 if (value < mc->min || value > mc->max) return -EINVAL; =20 + value =3D AW88261_MUTE_VOL - (value * 2); + if (vol_desc->ctl_volume !=3D value) { vol_desc->ctl_volume =3D value; aw88261_dev_set_volume(aw88261->aw_pa, vol_desc->ctl_volume); @@ -1000,10 +982,18 @@ static int aw88261_volume_set(struct snd_kcontrol *k= control, return 0; } =20 +/* + * The field contains 4 bits in units of 6dB + 6 bits in units of 0.125dB + * which is too precise for TLV (!) so we have to multiply the scale by 2. + * + * The range is clamped at -90dB to prevent overflowing the 4-bit part. + */ +static const DECLARE_TLV_DB_SCALE(volume_tlv, -9000, 25, 0); + static const struct snd_kcontrol_new aw88261_controls[] =3D { - SOC_SINGLE_EXT("PCM Playback Volume", AW88261_SYSCTRL2_REG, - 6, AW88261_MUTE_VOL, 0, aw88261_volume_get, - aw88261_volume_set), + SOC_SINGLE_EXT_TLV("PCM Playback Volume", AW88261_SYSCTRL2_REG, + 6, AW88261_MUTE_VOL / 2, 1, + aw88261_volume_get, aw88261_volume_set, volume_tlv), AW88261_PROFILE_EXT("Profile Set", aw88261_profile_info, aw88261_profile_get, aw88261_profile_set), }; diff --git a/sound/soc/codecs/aw88261.h b/sound/soc/codecs/aw88261.h index 1b1beba6a26b..76ef47236bb7 100644 --- a/sound/soc/codecs/aw88261.h +++ b/sound/soc/codecs/aw88261.h @@ -536,7 +536,6 @@ #define AW88261_DEV_SYSST_CHECK_MAX (10) #define AW88261_SOFT_RESET_VALUE (0x55aa) #define AW88261_REG_TO_DB (0x3f) -#define AW88261_VOL_START_MASK (0xfc00) #define AW88261_INIT_PROFILE (0) =20 #define REG_VAL_TO_DB(value) ((((value) >> AW88261_VOL_6DB_START) * \ --=20 2.53.0