Merge remote-tracking branch 'asoc/fix/sunxi' into asoc-linus
This commit is contained in:
commit
4d0210e6d0
|
@ -73,6 +73,7 @@
|
|||
#define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8)
|
||||
#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK GENMASK(5, 4)
|
||||
#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6)
|
||||
#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9)
|
||||
|
||||
struct sun8i_codec {
|
||||
struct device *dev;
|
||||
|
@ -170,11 +171,11 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
|||
|
||||
/* clock masters */
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */
|
||||
value = 0x0; /* Codec Master */
|
||||
case SND_SOC_DAIFMT_CBS_CFS: /* Codec slave, DAI master */
|
||||
value = 0x1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */
|
||||
value = 0x1; /* Codec Slave */
|
||||
case SND_SOC_DAIFMT_CBM_CFM: /* Codec Master, DAI slave */
|
||||
value = 0x0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -226,12 +227,57 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct sun8i_codec_clk_div {
|
||||
u8 div;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = {
|
||||
{ .div = 1, .val = 0 },
|
||||
{ .div = 2, .val = 1 },
|
||||
{ .div = 4, .val = 2 },
|
||||
{ .div = 6, .val = 3 },
|
||||
{ .div = 8, .val = 4 },
|
||||
{ .div = 12, .val = 5 },
|
||||
{ .div = 16, .val = 6 },
|
||||
{ .div = 24, .val = 7 },
|
||||
{ .div = 32, .val = 8 },
|
||||
{ .div = 48, .val = 9 },
|
||||
{ .div = 64, .val = 10 },
|
||||
{ .div = 96, .val = 11 },
|
||||
{ .div = 128, .val = 12 },
|
||||
{ .div = 192, .val = 13 },
|
||||
};
|
||||
|
||||
static u8 sun8i_codec_get_bclk_div(struct sun8i_codec *scodec,
|
||||
unsigned int rate,
|
||||
unsigned int word_size)
|
||||
{
|
||||
unsigned long clk_rate = clk_get_rate(scodec->clk_module);
|
||||
unsigned int div = clk_rate / rate / word_size / 2;
|
||||
unsigned int best_val = 0, best_diff = ~0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sun8i_codec_bclk_div); i++) {
|
||||
const struct sun8i_codec_clk_div *bdiv = &sun8i_codec_bclk_div[i];
|
||||
unsigned int diff = abs(bdiv->div - div);
|
||||
|
||||
if (diff < best_diff) {
|
||||
best_diff = diff;
|
||||
best_val = bdiv->val;
|
||||
}
|
||||
}
|
||||
|
||||
return best_val;
|
||||
}
|
||||
|
||||
static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
|
||||
int sample_rate;
|
||||
u8 bclk_div;
|
||||
|
||||
/*
|
||||
* The CPU DAI handles only a sample of 16 bits. Configure the
|
||||
|
@ -241,6 +287,11 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
|
|||
SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK,
|
||||
SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16);
|
||||
|
||||
bclk_div = sun8i_codec_get_bclk_div(scodec, params_rate(params), 16);
|
||||
regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
|
||||
SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK,
|
||||
bclk_div << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV);
|
||||
|
||||
regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
|
||||
SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK,
|
||||
SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16);
|
||||
|
|
Loading…
Reference in New Issue