Hello,
Background: What I'm trying to do is to add an additional SGTL5000 codec to my own motherboard PCB in additional to the one that already is present on my SOM board.
- The one on the SOM works fine by itself (Connected to SAI1 and I2C2)
The canges I've made so far are the following:
- Added an additional SGTL5000 on my board to SAI2 & I2C4
- The connections are exactly the same as for the one on the SOM
- Made changes to the DTS
- Made changes to a patch file that I think enables the MCLK
sound {
compatible = "fsl,imx-audio-sgtl5000";
model = "imx6ul-sgtl5000";
audio-cpu = <&sai1>;
audio-codec = <&codec>;
audio-routing =
"LINE_IN", "Line In Jack",
"MIC_IN", "Mic Jack",
"Mic Jack", "Mic Bias",
"Headphone Jack", "HP_OUT";
};
sound2 {
compatible = "fsl,imx-audio-sgtl5000";
model = "imx6ul-sgtl5000";
audio-cpu = <&sai2>;
audio-codec = <&codec2>;
audio-routing =
"LINE_IN", "Line In Jack",
"MIC_IN", "Mic Jack",
"Mic Jack", "Mic Bias",
"Headphone Jack", "HP_OUT";
};
&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <786432000>;
};
&i2c4 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
status = "okay";
codec2: sgtl5000@0a {
reg = <0x0a>;
compatible = "fsl,sgtl5000";
clocks = <&clks IMX6UL_CLK_SAI2>;
assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
<&clks IMX6UL_CLK_SAI2>;
assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <0>, <24576000>;
gpr = <&gpr>;
VDDA-supply = <®_3p3v>;
VDDIO-supply = <®_3p3v>;
};
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
codec: sgtl5000@0a {
reg = <0x0a>;
compatible = "fsl,sgtl5000";
clocks = <&clks IMX6UL_CLK_SAI1>;
assigned-clocks = <&clks IMX6UL_CLK_SAI1_SEL>,
<&clks IMX6UL_CLK_SAI1>;
assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <0>, <24576000>;
gpr = <&gpr>;
VDDA-supply = <®_3p3v>;
VDDIO-supply = <®_3p3v>;
};
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-nxpu-iopb {
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_CSI_DATA01__SAI1_MCLK 0x17088 I wonder why this one is here and not in the SAI1grp?
>;
};
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO02__I2C1_SCL 0x4001b8b0
MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x4001b8b0
>;
};
pinctrl_i2c2: i2c2grp {
fsl,pins = <
MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
MX6UL_PAD_CSI_VSYNC__I2C2_SDA 0x4001b8b0
>;
};
pinctrl_i2c4: i2c4grp {
fsl,pins = <
MX6UL_PAD_ENET2_TX_DATA0__I2C4_SDA 0x4001b8b0
MX6UL_PAD_ENET2_RX_EN__I2C4_SCL 0x4001b8b0
>;
};
pinctrl_sai1: sai1grp {
fsl,pins = <
MX6UL_PAD_CSI_DATA07__SAI1_TX_DATA 0x17088
MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA 0x17088
MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK 0x17088
MX6UL_PAD_CSI_DATA04__SAI1_TX_SYNC 0x17088
>;
};
pinctrl_sai2: sai2grp {
fsl,pins = <
MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088
MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088
MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x11088 /* 120b0 */
MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x11088 /* 130b0 */
MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x17088
>;
};
&sai1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1>;
status = "okay";
};
&sai2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai2>;
status = "okay";
};
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 974ba70..63302d2 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -10,7 +10,6 @@ snd-soc-core-objs += soc-ac97.o
endif
obj-$(CONFIG_SND_SOC) += snd-soc-core.o
-obj-$(CONFIG_SND_SOC) += codecs/
obj-$(CONFIG_SND_SOC) += generic/
obj-$(CONFIG_SND_SOC) += adi/
obj-$(CONFIG_SND_SOC) += atmel/
@@ -38,3 +37,4 @@ obj-$(CONFIG_SND_SOC) += tegra/
obj-$(CONFIG_SND_SOC) += txx9/
obj-$(CONFIG_SND_SOC) += ux500/
obj-$(CONFIG_SND_SOC) += xtensa/
+obj-$(CONFIG_SND_SOC) += codecs/
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 3a29c0a..e1d582a 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -29,6 +29,7 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
+#include <linux/mfd/syscon.h>
#include "sgtl5000.h"
@@ -1428,11 +1429,14 @@ static int sgtl5000_fill_defaults(struct sgtl5000_priv *sgtl5000)
static int sgtl5000_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device_node *gpr_np;
+ struct regmap *gpr;
struct sgtl5000_priv *sgtl5000;
int ret, reg, rev;
struct device_node *np = client->dev.of_node;
u32 value;
+
sgtl5000 = devm_kzalloc(&client->dev, sizeof(*sgtl5000), GFP_KERNEL);
if (!sgtl5000)
return -ENOMEM;
@@ -1458,6 +1462,18 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
if (ret)
return ret;
+ gpr_np = of_parse_phandle(client->dev.of_node, "gpr", 0);
+ if (gpr_np) {
+ gpr = syscon_node_to_regmap(gpr_np);
+ if (IS_ERR(gpr)) {
+ ret = PTR_ERR(gpr);
+ dev_err(&client->dev, "failed to get gpr regmap\n");
+ return ret;
+ }
+ /* set SAI1_MCLK_DIR to enable codec MCLK for imx6ul */
+ regmap_update_bits(gpr, 4, 1<<19, 1<<19);
+ regmap_update_bits(gpr, 4, 1<<20, 1<<20);
+ }
+
/* Need 8 clocks before I2C accesses */
udelay(1);
- I assume that the regmap_update_bits(gpr, 4, 1<<20, 1<<20); needs to be done here in order to set the direction for the SAI2 MCLK also?
fsl-asrc 2034000.asrc: driver registered
imx-sgtl5000 sound: mux-int-port missing or invalid
imx-sgtl5000: probe of sound failed with error -22
imx-sgtl5000 sound2: mux-int-port missing or invalid
imx-sgtl5000: probe of sound2 failed with error -22
sgtl5000 1-000a: sgtl5000 revision 0x11
sgtl5000: probe of 3-000a failed with error -5
and naturally later on:
ALSA device list:
No soundcards found.
This means that now neither one of the Codecs are working.
Could anyone point me in the right direction or enlighten me what I have missed or done wrong?
If only the I2C works and there is no MCLK etc. Should I still be able to see the additional codec with, for example, i2cdetect? Because now I only see the codec connected to i2c2.
Thanks in advance,
Jonas
Hi Jonas
one can look at patch
error "imx-sgtl5000 sound: mux-int-port missing or invalid" may mean that there may be left
entries from audmux-ssi, used on i.MX6DQ/SDL.
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Igor,
Thanks for your reply and the link.
One question that confuses me is that, the codec on the SOM works perfectly alone (with the patch file above).
But, when I add the changes to the DTS and + regmap_update_bits(gpr, 4, 1<<20, 1<<20); in the patch, I get the above errors: error "imx-sgtl5000 sound: mux-int-port missing or invalid".
Could it be something with loading the same driver two times? Or is it something else that has to be done for the SAI2 interface, and at the same time confuses the existing SAI1 configuration?
If the Codec on my baseboard would be defect or some connections wrong I would expect the SOM codec to still work.
I have to cross-check this also by first removing the SOM codec from the DTS and only use the baseboard codec and see if the baseboard codec will work alone.
Kind regards,
Jonas
Hi Jonas,
I have a trouble with the sgtl5000 on imx6ul board,too. And It also come out the error log just like "imx-sgtl5000 sound: mux-int-port missing or invalid imx-sgtl5000: probe of sound failed with error -22". As Igor said that there were two path could solve this problem , but the link just have one path , could you provide the first path to me ? Thanks .
Best regards
Jun
Hi Jonas
one can check if regmap is changing sai configurations using gpr
registers described in Chapter 30 i.MX6UL Reference Manual.
Best regards
igor
Hi Igor,
Is there any easy way to read these registers?
Regards,
Jonas
Hi Jonas
please try memtool
Hi Igor,
I got the codec to work (Just writing here if anyone else struggles with something similar):
First thing was a brainfart to enable the SAI1 & SAI2 clocks.
This
""
+ regmap_update_bits(gpr, 4, 1<<19, 1<<19);
+ regmap_update_bits(gpr, 4, 1<<20, 1<<20);
""
Should of course be:
+ regmap_update_bits(gpr, 4, 3<<19, 3<<19);
Otherwise we are moving all the previous bits again.
The other thing after that was a problem with the driver and LDO (VDDD) initialization because the driver was loaded two times.
This can be solved with the following patch in this thread:
https://community.nxp.com/thread/377866
Kind regards,
Jonas
And thanks for your input Igor!