diff options
-rw-r--r-- | sound/soc/loongson/loongson_i2s.c | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/sound/soc/loongson/loongson_i2s.c b/sound/soc/loongson/loongson_i2s.c index 8bb38e418333..40bbf3205391 100644 --- a/sound/soc/loongson/loongson_i2s.c +++ b/sound/soc/loongson/loongson_i2s.c @@ -24,6 +24,9 @@ #define LOONGSON_I2S_TX_ENABLE (I2S_CTRL_TX_EN | I2S_CTRL_TX_DMA_EN) #define LOONGSON_I2S_RX_ENABLE (I2S_CTRL_RX_EN | I2S_CTRL_RX_DMA_EN) +#define LOONGSON_I2S_DEF_DELAY 10 +#define LOONGSON_I2S_DEF_TIMEOUT 500000 + static int loongson_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -119,10 +122,40 @@ static int loongson_i2s_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, return 0; } +static int loongson_i2s_enable_mclk(struct loongson_i2s *i2s) +{ + u32 val; + + if (i2s->rev_id == 0) + return 0; + + regmap_update_bits(i2s->regmap, LS_I2S_CTRL, + I2S_CTRL_MCLK_EN, I2S_CTRL_MCLK_EN); + + return regmap_read_poll_timeout_atomic(i2s->regmap, + LS_I2S_CTRL, val, + val & I2S_CTRL_MCLK_READY, + LOONGSON_I2S_DEF_DELAY, + LOONGSON_I2S_DEF_TIMEOUT); +} + +static int loongson_i2s_enable_bclk(struct loongson_i2s *i2s) +{ + u32 val; + + if (i2s->rev_id == 0) + return 0; + + return regmap_read_poll_timeout_atomic(i2s->regmap, + LS_I2S_CTRL, val, + val & I2S_CTRL_CLK_READY, + LOONGSON_I2S_DEF_DELAY, + LOONGSON_I2S_DEF_TIMEOUT); +} + static int loongson_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct loongson_i2s *i2s = snd_soc_dai_get_drvdata(dai); - u32 val; int ret; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -144,54 +177,29 @@ static int loongson_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) /* Enable master mode */ regmap_update_bits(i2s->regmap, LS_I2S_CTRL, I2S_CTRL_MASTER, I2S_CTRL_MASTER); - if (i2s->rev_id == 1) { - ret = regmap_read_poll_timeout_atomic(i2s->regmap, - LS_I2S_CTRL, val, - val & I2S_CTRL_CLK_READY, - 10, 500000); - if (ret < 0) - dev_warn(dai->dev, "wait BCLK ready timeout\n"); - } + ret = loongson_i2s_enable_bclk(i2s); + if (ret < 0) + dev_warn(dai->dev, "wait BCLK ready timeout\n"); break; case SND_SOC_DAIFMT_BC_FP: /* Enable MCLK */ - if (i2s->rev_id == 1) { - regmap_update_bits(i2s->regmap, LS_I2S_CTRL, - I2S_CTRL_MCLK_EN, - I2S_CTRL_MCLK_EN); - ret = regmap_read_poll_timeout_atomic(i2s->regmap, - LS_I2S_CTRL, val, - val & I2S_CTRL_MCLK_READY, - 10, 500000); - if (ret < 0) - dev_warn(dai->dev, "wait MCLK ready timeout\n"); - } + ret = loongson_i2s_enable_mclk(i2s); + if (ret < 0) + dev_warn(dai->dev, "wait MCLK ready timeout\n"); break; case SND_SOC_DAIFMT_BP_FP: /* Enable MCLK */ - if (i2s->rev_id == 1) { - regmap_update_bits(i2s->regmap, LS_I2S_CTRL, - I2S_CTRL_MCLK_EN, - I2S_CTRL_MCLK_EN); - ret = regmap_read_poll_timeout_atomic(i2s->regmap, - LS_I2S_CTRL, val, - val & I2S_CTRL_MCLK_READY, - 10, 500000); - if (ret < 0) - dev_warn(dai->dev, "wait MCLK ready timeout\n"); - } + ret = loongson_i2s_enable_mclk(i2s); + if (ret < 0) + dev_warn(dai->dev, "wait MCLK ready timeout\n"); /* Enable master mode */ regmap_update_bits(i2s->regmap, LS_I2S_CTRL, I2S_CTRL_MASTER, I2S_CTRL_MASTER); - if (i2s->rev_id == 1) { - ret = regmap_read_poll_timeout_atomic(i2s->regmap, - LS_I2S_CTRL, val, - val & I2S_CTRL_CLK_READY, - 10, 500000); - if (ret < 0) - dev_warn(dai->dev, "wait BCLK ready timeout\n"); - } + + ret = loongson_i2s_enable_bclk(i2s); + if (ret < 0) + dev_warn(dai->dev, "wait BCLK ready timeout\n"); break; default: return -EINVAL; |