struct reg_field                field_fmt_bclk;
        struct reg_field                field_fmt_lrclk;
 
+       unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *);
        s8      (*get_sr)(const struct sun4i_i2s *, int);
        s8      (*get_wss)(const struct sun4i_i2s *, int);
        int     (*set_chan_cfg)(const struct sun4i_i2s *,
        /* TODO - extend divide ratio supported by newer SoCs */
 };
 
+static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
+{
+       return i2s->mclk_freq;
+}
+
+static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
+{
+       return clk_get_rate(i2s->mod_clk);
+}
+
 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
                                  unsigned long parent_rate,
                                  unsigned int sampling_rate,
                                  unsigned int word_size)
 {
        struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-       unsigned int oversample_rate, clk_rate;
+       unsigned int oversample_rate, clk_rate, bclk_parent_rate;
        int bclk_div, mclk_div;
        int ret;
 
                return -EINVAL;
        }
 
-       bclk_div = sun4i_i2s_get_bclk_div(i2s, i2s->mclk_freq,
+       bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
+       bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
                                          rate, word_size);
        if (bclk_div < 0) {
                dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
        .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
        .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
+       .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
        .get_sr                 = sun4i_i2s_get_sr,
        .get_wss                = sun4i_i2s_get_wss,
        .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
        .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
        .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
+       .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
        .get_sr                 = sun4i_i2s_get_sr,
        .get_wss                = sun4i_i2s_get_wss,
        .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
        .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
        .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
+       .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
        .get_sr                 = sun8i_i2s_get_sr_wss,
        .get_wss                = sun8i_i2s_get_sr_wss,
        .set_chan_cfg           = sun8i_i2s_set_chan_cfg,
        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
        .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
        .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19),
+       .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
        .get_sr                 = sun8i_i2s_get_sr_wss,
        .get_wss                = sun8i_i2s_get_sr_wss,
        .set_chan_cfg           = sun8i_i2s_set_chan_cfg,
        .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
        .field_fmt_bclk         = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6),
        .field_fmt_lrclk        = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7),
+       .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
        .get_sr                 = sun4i_i2s_get_sr,
        .get_wss                = sun4i_i2s_get_wss,
        .set_chan_cfg           = sun4i_i2s_set_chan_cfg,