Skip to content

Commit

Permalink
ASoC: meson: aiu: add support for the Meson8 and Meson8b SoC families
Browse files Browse the repository at this point in the history
The AIU audio controller on the Meson8 and Meson8b SoC families is
compatible with the one found in the later GXBB family. Add compatible
strings for these two older SoC families so the driver can be loaded for
them.

Instead of using the I2S divider from the AIU_CLK_CTRL_MORE register we
need to use the I2S divider from the AIU_CLK_CTRL register. This older
register is less flexible because it only supports four divider settings
(1, 2, 4, 8) compared to the AIU_CLK_CTRL_MORE register (which supports
dividers in the range 0..64).

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
  • Loading branch information
xdarklight committed Feb 16, 2020
1 parent bdac178 commit 5cecc91
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
2 changes: 1 addition & 1 deletion sound/soc/meson/Kconfig
Expand Up @@ -9,7 +9,7 @@ config SND_MESON_AIU
imply SND_SOC_HDMI_CODEC if DRM_MESON_DW_HDMI
help
Select Y or M to add support for the Audio output subsystem found
in the Amlogic GX SoC family
in the Amlogic Meson8, Meson8b and GX SoC families

config SND_MESON_AXG_FIFO
tristate
Expand Down
21 changes: 16 additions & 5 deletions sound/soc/meson/aiu-encoder-i2s.c
Expand Up @@ -116,6 +116,7 @@ static int aiu_encoder_i2s_set_clocks(struct snd_soc_component *component,
{
struct aiu *aiu = snd_soc_component_get_drvdata(component);
unsigned int srate = params_rate(params);
u8 i2s_div, more_i2s_div;
unsigned int fs, bs;

/* Get the oversampling factor */
Expand All @@ -135,10 +136,6 @@ static int aiu_encoder_i2s_set_clocks(struct snd_soc_component *component,
FIELD_PREP(AIU_CODEC_DAC_LRCLK_CTRL_DIV,
64 - 1));

/* Use CLK_MORE for mclk to bclk divider */
snd_soc_component_update_bits(component, AIU_CLK_CTRL,
AIU_CLK_CTRL_I2S_DIV, 0);

/*
* NOTE: this HW is odd.
* In most configuration, the i2s divider is 'mclk / blck'.
Expand All @@ -156,10 +153,24 @@ static int aiu_encoder_i2s_set_clocks(struct snd_soc_component *component,
bs += bs / 2;
}

if (aiu->platform->has_clk_ctrl_more_i2s_div) {
/* Use CLK_MORE for mclk to bclk divider */
i2s_div = 0;
more_i2s_div = bs - 1;
} else {
i2s_div = __ffs(bs);

This comment has been minimized.

Copy link
@jeromebrunet

jeromebrunet Feb 17, 2020

I wonder if we should check that calculation is correct ? IOW (out of range, remainder?)

This comment has been minimized.

Copy link
@xdarklight

xdarklight Feb 17, 2020

Author Owner

makes sense, I'll fix that

more_i2s_div = 0;
}

snd_soc_component_update_bits(component, AIU_CLK_CTRL,
AIU_CLK_CTRL_I2S_DIV,
FIELD_PREP(AIU_CLK_CTRL_I2S_DIV,
i2s_div));

snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE,

This comment has been minimized.

Copy link
@jeromebrunet

jeromebrunet Feb 17, 2020

Maybe move it in the "if" clause to write only if the SoC has this register.
I even wonder if two function (legacy_i2s_div(), clk_more_i2s_div()) would help make things clear ?

This comment has been minimized.

Copy link
@xdarklight

xdarklight Feb 17, 2020

Author Owner

that's a great idea, I think that this will simplify things a lot
I'll report back once I've actually tried it

AIU_CLK_CTRL_MORE_I2S_DIV,
FIELD_PREP(AIU_CLK_CTRL_MORE_I2S_DIV,
bs - 1));
more_i2s_div));

/* Make sure amclk is used for HDMI i2s as well */
snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE,
Expand Down
9 changes: 9 additions & 0 deletions sound/soc/meson/aiu.c
Expand Up @@ -371,15 +371,24 @@ static int aiu_remove(struct platform_device *pdev)

static const struct aiu_platform_data aiu_gxbb_pdata = {
.has_acodec = false,
.has_clk_ctrl_more_i2s_div = true,
};

static const struct aiu_platform_data aiu_gxl_pdata = {
.has_acodec = true,
.has_clk_ctrl_more_i2s_div = true,
};

static const struct aiu_platform_data aiu_meson8_pdata = {
.has_acodec = false,
.has_clk_ctrl_more_i2s_div = false,

This comment has been minimized.

Copy link
@jeromebrunet

jeromebrunet Feb 17, 2020

has_clk_more is probably enough

This comment has been minimized.

Copy link
@xdarklight

xdarklight Feb 17, 2020

Author Owner

the CLK_CTRL_MORE register exists and it contains bit 6 for the HDMI mux
however, this register is missing the I2S divider bits

this is the reason why I went for this longer, but more descriptive name

This comment has been minimized.

Copy link
@jeromebrunet

jeromebrunet Feb 18, 2020

Fine then. If you find a way to shorten it a bit, it's great ... if not, so be it ;)

};

static const struct of_device_id aiu_of_match[] = {
{ .compatible = "amlogic,aiu-gxbb", .data = &aiu_gxbb_pdata },
{ .compatible = "amlogic,aiu-gxl", .data = &aiu_gxl_pdata },
{ .compatible = "amlogic,aiu-meson8", .data = &aiu_meson8_pdata },
{ .compatible = "amlogic,aiu-meson8b", .data = &aiu_meson8_pdata },
{}
};
MODULE_DEVICE_TABLE(of, aiu_of_match);
Expand Down
1 change: 1 addition & 0 deletions sound/soc/meson/aiu.h
Expand Up @@ -31,6 +31,7 @@ struct aiu_interface {

struct aiu_platform_data {
bool has_acodec;
bool has_clk_ctrl_more_i2s_div;
};

struct aiu {
Expand Down

0 comments on commit 5cecc91

Please sign in to comment.