ASoC: tlv320aic32x4: Fix the divide by zero

The value of register(NDAC,MDAC,NADC,MADC,BCLKN) maybe zero lead to
divide by zero in clk_aic32x4_div_recalc_rate().And the rate should be
divide by 128 if the value was zero in this function according to the
datasheet.

Add the macro AIC32X4_DIV_MAX to present the 128 and return 0 if failing
to read the value of register.

Signed-off-by: Guiting Shen <aarongt.shen@gmail.com>
Link: https://lore.kernel.org/r/20230813125520.11067-1-aarongt.shen@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Guiting Shen 2023-08-13 20:55:20 +08:00 committed by Mark Brown
parent b39eee2754
commit 11e756cc85
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 14 additions and 7 deletions

View File

@ -321,7 +321,7 @@ static int clk_aic32x4_div_set_rate(struct clk_hw *hw, unsigned long rate,
u8 divisor;
divisor = DIV_ROUND_UP(parent_rate, rate);
if (divisor > 128)
if (divisor > AIC32X4_DIV_MAX)
return -EINVAL;
return regmap_update_bits(div->regmap, div->reg,
@ -334,7 +334,7 @@ static int clk_aic32x4_div_determine_rate(struct clk_hw *hw,
unsigned long divisor;
divisor = DIV_ROUND_UP(req->best_parent_rate, req->rate);
if (divisor > 128)
if (divisor > AIC32X4_DIV_MAX)
return -EINVAL;
req->rate = DIV_ROUND_UP(req->best_parent_rate, divisor);
@ -345,12 +345,18 @@ static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_aic32x4 *div = to_clk_aic32x4(hw);
unsigned int val;
int err;
regmap_read(div->regmap, div->reg, &val);
err = regmap_read(div->regmap, div->reg, &val);
if (err)
return 0;
return DIV_ROUND_UP(parent_rate, val & AIC32X4_DIV_MASK);
val &= AIC32X4_DIV_MASK;
if (!val)
val = AIC32X4_DIV_MAX;
return DIV_ROUND_UP(parent_rate, val);
}
static const struct clk_ops aic32x4_div_ops = {

View File

@ -223,8 +223,9 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
#define AIC32X4_REFPOWERUP_120MS 0x07
/* Common mask and enable for all of the dividers */
#define AIC32X4_DIVEN BIT(7)
#define AIC32X4_DIV_MASK GENMASK(6, 0)
#define AIC32X4_DIVEN BIT(7)
#define AIC32X4_DIV_MASK GENMASK(6, 0)
#define AIC32X4_DIV_MAX 128
/* Clock Limits */
#define AIC32X4_MAX_DOSR_FREQ 6200000