Commit 4d0210e6 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/fix/sunxi' into asoc-linus

parents 60190e46 316b7758
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
#define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8) #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_WORD_SIZ_MASK GENMASK(5, 4)
#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6) #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 sun8i_codec {
struct device *dev; struct device *dev;
...@@ -170,11 +171,11 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -170,11 +171,11 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
/* clock masters */ /* clock masters */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */ case SND_SOC_DAIFMT_CBS_CFS: /* Codec slave, DAI master */
value = 0x0; /* Codec Master */ value = 0x1;
break; break;
case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */ case SND_SOC_DAIFMT_CBM_CFM: /* Codec Master, DAI slave */
value = 0x1; /* Codec Slave */ value = 0x0;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -226,12 +227,57 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -226,12 +227,57 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0; 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, static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec); struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
int sample_rate; int sample_rate;
u8 bclk_div;
/* /*
* The CPU DAI handles only a sample of 16 bits. Configure the * 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, ...@@ -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_MASK,
SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16); 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, regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK, SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK,
SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16); SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment