The AW88258 has a slightly different register map, namely the PLL ones are different and some extra boost ones are absent. Before the recent hw_params fix, the PLL CCO_MUX accesses were actually always wrong as the PLLCTRL1 address (0x54) was from the AW88261 but the CCO_MUX offset (14) was from the AW88258. With said fix the AW88261 parameters were always used, making it work on that chip. Make the accesses correct for the AW88258 as well.
Signed-off-by: Val Packett <[email protected]> --- This one is not tested (don't have the hardware), but since I've noticed that the CCO_MUX was not even correct for any of the supported chips, I've decided to try fixing it for the other one as well. Code style wise this is kind of a really annoying situation but hopefully this looks okay enough ~val --- sound/soc/codecs/aw88258.h | 34 ++++++++++++++++++++++++++++++++++ sound/soc/codecs/aw88261.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 sound/soc/codecs/aw88258.h diff --git a/sound/soc/codecs/aw88258.h b/sound/soc/codecs/aw88258.h new file mode 100644 index 000000000000..7ae177667ae6 --- /dev/null +++ b/sound/soc/codecs/aw88258.h @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// aw88258.h -- AW88258 ALSA SoC Audio driver +// +// Copyright (c) 2023 awinic Technology CO., LTD +// +// Author: Jimmy Zhang <[email protected]> +// Author: Weidong Wang <[email protected]> +// + +#ifndef __AW88258_H__ +#define __AW88258_H__ + +/* This file contains definitions for registers that differ between + * the AW88261 (ID 0x2113) and the AW88258 (ID 0x1852). */ + +#define AW88258_PLLCTRL1_REG (0x66) +#define AW88258_PLLCTRL2_REG (0x67) +#define AW88258_PLLCTRL3_REG (0x68) + +#define AW88258_CCO_MUX_START_BIT (14) +#define AW88258_CCO_MUX_BITS_LEN (1) +#define AW88258_CCO_MUX_MASK \ + (~(((1<<AW88258_CCO_MUX_BITS_LEN)-1) << AW88258_CCO_MUX_START_BIT)) + +#define AW88258_CCO_MUX_DIVIDED (0) +#define AW88258_CCO_MUX_DIVIDED_VALUE \ + (AW88258_CCO_MUX_DIVIDED << AW88258_CCO_MUX_START_BIT) + +#define AW88258_CCO_MUX_BYPASS (1) +#define AW88258_CCO_MUX_BYPASS_VALUE \ + (AW88258_CCO_MUX_BYPASS << AW88258_CCO_MUX_START_BIT) + +#endif diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index 3c7d3e3865eb..172f38a4921c 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -14,6 +14,7 @@ #include <linux/regulator/consumer.h> #include <sound/soc.h> #include <sound/pcm_params.h> +#include "aw88258.h" #include "aw88261.h" #include "aw88395/aw88395_data_type.h" #include "aw88395/aw88395_device.h" @@ -179,37 +180,36 @@ static int aw88261_dev_check_pll(struct aw_device *aw_dev) static int aw88261_dev_configure_syspll(struct aw88261 *aw88261) { struct aw_device *aw_dev = aw88261->aw_pa; - uint32_t sr_value, fs_value, cco_mux_value, bck_value; + uint32_t sr_value, fs_value, bck_value; + bool bypass_divider = false; int ret; switch (aw88261->sample_rate) { case 8000: sr_value = AW88261_I2SSR_8KHZ_VALUE; - cco_mux_value = AW88261_CCO_MUX_DIVIDED_VALUE; break; case 16000: sr_value = AW88261_I2SSR_16KHZ_VALUE; - cco_mux_value = AW88261_CCO_MUX_DIVIDED_VALUE; break; case 32000: sr_value = AW88261_I2SSR_32KHZ_VALUE; - cco_mux_value = AW88261_CCO_MUX_DIVIDED_VALUE; + bypass_divider = true; break; case 44100: sr_value = AW88261_I2SSR_44P1KHZ_VALUE; - cco_mux_value = AW88261_CCO_MUX_BYPASS_VALUE; + bypass_divider = true; break; case 48000: sr_value = AW88261_I2SSR_48KHZ_VALUE; - cco_mux_value = AW88261_CCO_MUX_BYPASS_VALUE; + bypass_divider = true; break; case 96000: sr_value = AW88261_I2SSR_96KHZ_VALUE; - cco_mux_value = AW88261_CCO_MUX_BYPASS_VALUE; + bypass_divider = true; break; case 192000: sr_value = AW88261_I2SSR_192KHZ_VALUE; - cco_mux_value = AW88261_CCO_MUX_BYPASS_VALUE; + bypass_divider = true; break; default: dev_err(aw_dev->dev, "unsupported sample rate %d\n", @@ -241,8 +241,21 @@ static int aw88261_dev_configure_syspll(struct aw88261 *aw88261) } /* PLL divider must be used for 8/16/32 kHz modes */ - ret = regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG, - ~AW88261_CCO_MUX_MASK, cco_mux_value); + switch (aw_dev->chip_id) { + case AW88261_CHIP_ID: + ret = regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG, + ~AW88261_CCO_MUX_MASK, bypass_divider ? + AW88261_CCO_MUX_BYPASS_VALUE : AW88261_CCO_MUX_DIVIDED); + break; + case AW88258_CHIP_ID: + ret = regmap_update_bits(aw_dev->regmap, AW88258_PLLCTRL1_REG, + ~AW88258_CCO_MUX_MASK, bypass_divider ? + AW88258_CCO_MUX_BYPASS_VALUE : AW88258_CCO_MUX_DIVIDED); + break; + default: + WARN_ONCE(1, "missing PLL regs for chip %x", aw_dev->chip_id); + return -ENXIO; + } if (ret) return ret; @@ -306,7 +319,9 @@ static void aw88261_dev_uls_hmute(struct aw_device *aw_dev, bool uls_hmute) static void aw88261_reg_force_set(struct aw88261 *aw88261) { - if (aw88261->frcset_en == AW88261_FRCSET_ENABLE) { + if (aw88261->aw_pa->chip_id == AW88258_CHIP_ID) { + dev_dbg(aw88261->aw_pa->dev, "force_set not supported on aw88258"); + } else if (aw88261->frcset_en == AW88261_FRCSET_ENABLE) { /* set FORCE_PWM */ regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL3_REG, AW88261_FORCE_PWM_MASK, AW88261_FORCE_PWM_FORCEMINUS_PWM_VALUE); -- 2.53.0

