Hello Jon,
The audio codec I used is tlv320aic3104 instead the one which Igal was using.
Moreover, there related source files are different.
(mine is tlv320aic3x.c and Igal’s is tlv320aic32x4.c)
Therefore, I could try my best to follow the Igal’s steps.
Below is the diff of my modifications:
- tlv320aic3x.c
diff --git a/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c b/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
index a564759..baeda3e 100644
--- a/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
+++ b/kernel/kernel-4.4/sound/soc/codecs/tlv320aic3x.c
@@ -50,6 +50,7 @@
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/tlv320aic3x.h>
+#include <dt-bindings/gpio/tegra186-gpio.h>
#include "tlv320aic3x.h"
@@ -93,6 +94,8 @@ struct aic3x_priv {
/* Selects the micbias voltage */
enum aic3x_micbias_voltage micbias_vg;
+ /* Output Common-Mode Voltage */
+ u8 ocmv;
};
static const struct reg_default aic3x_reg[] = {
@@ -126,6 +129,16 @@ static const struct reg_default aic3x_reg[] = {
{ 108, 0x00 }, { 109, 0x00 },
};
+static bool aic3x_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case AIC3X_RESET:
+ return true;
+ default:
+ return false;
+ }
+}
+
static const struct regmap_config aic3x_regmap = {
.reg_bits = 8,
.val_bits = 8,
@@ -133,6 +146,9 @@ static const struct regmap_config aic3x_regmap = {
.max_register = DAC_ICC_ADJ,
.reg_defaults = aic3x_reg,
.num_reg_defaults = ARRAY_SIZE(aic3x_reg),
+
+ .volatile_reg = aic3x_volatile_reg,
+
.cache_type = REGCACHE_RBTREE,
};
@@ -157,7 +173,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
unsigned short val;
- struct snd_soc_dapm_update update;
+ struct snd_soc_dapm_update update = {};
int connect, change;
val = (ucontrol->value.integer.value[0] & mask);
@@ -615,7 +631,7 @@ SOC_DAPM_ENUM("Route", aic3x_line2r_2_rdac_enum);
static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
/* Left DAC to Left Outputs */
- SND_SOC_DAPM_DAC("Left DAC", "Left Playback", DAC_PWR, 7, 0),
+ SND_SOC_DAPM_DAC("Left DAC", "Playback", DAC_PWR, 7, 0),
SND_SOC_DAPM_MUX("Left DAC Mux", SND_SOC_NOPM, 0, 0,
&aic3x_left_dac_mux_controls),
SND_SOC_DAPM_MUX("Left HPCOM Mux", SND_SOC_NOPM, 0, 0,
@@ -625,7 +641,7 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
SND_SOC_DAPM_PGA("Left HP Com", HPLCOM_CTRL, 0, 0, NULL, 0),
/* Right DAC to Right Outputs */
- SND_SOC_DAPM_DAC("Right DAC", "Right Playback", DAC_PWR, 6, 0),
+ SND_SOC_DAPM_DAC("Right DAC", "Playback", DAC_PWR, 6, 0),
SND_SOC_DAPM_MUX("Right DAC Mux", SND_SOC_NOPM, 0, 0,
&aic3x_right_dac_mux_controls),
SND_SOC_DAPM_MUX("Right HPCOM Mux", SND_SOC_NOPM, 0, 0,
@@ -635,14 +651,14 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
SND_SOC_DAPM_PGA("Right HP Com", HPRCOM_CTRL, 0, 0, NULL, 0),
/* Inputs to Left ADC */
- SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
+ SND_SOC_DAPM_ADC("Left ADC", "Capture", LINE1L_2_LADC_CTRL, 2, 0),
SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
&aic3x_left_line1l_mux_controls),
SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
&aic3x_left_line1r_mux_controls),
/* Inputs to Right ADC */
- SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
+ SND_SOC_DAPM_ADC("Right ADC", "Capture",
LINE1R_2_RADC_CTRL, 2, 0),
SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
&aic3x_right_line1l_mux_controls),
@@ -1020,6 +1036,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
+#if 1
struct snd_soc_codec *codec = dai->codec;
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
@@ -1027,10 +1044,12 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
u16 d, pll_d = 1;
int clk;
int width = aic3x->slot_width;
+ printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__);
if (!width)
width = params_width(params);
+
/* select data word length */
data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
switch (width) {
@@ -1046,6 +1065,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
data |= (0x03 << 4);
break;
}
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_ASD_INTF_CTRLB, width=%d, data=%d\n\n", width, data);
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, data);
/* Fsref can be 44100 or 48000 */
@@ -1060,13 +1080,18 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
}
if (bypass_pll) {
+ printk(KERN_ERR "Bypass PLL\n\n\n\n");
pll_q &= 0xf;
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGA_REG=%d\n\n", pll_q << PLLQ_SHIFT);
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_GPIOB_REG=%d\n\n", CODEC_CLKIN_CLKDIV);
snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
/* disable PLL if it is bypassed */
snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
} else {
+ printk(KERN_ERR "[CTTest-hw_param] Use PLL\n\n");
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_GPIOB_REG=%d\n\n", CODEC_CLKIN_PLLDIV);
snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
/* enable PLL when it is used */
snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
@@ -1079,6 +1104,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
if (params_rate(params) >= 64000)
data |= DUAL_RATE_MODE;
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_CODEC_DATAPATH_REG=%d\n\n", data);
snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
/* codec sample rate select */
@@ -1088,6 +1114,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
data /= 5;
data -= 2;
data |= (data << 4);
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_SAMPLE_RATE_SEL_REG=%d\n\n", data);
snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
if (bypass_pll)
@@ -1157,7 +1184,12 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
}
found:
+ printk(KERN_ERR "[CTTest-hw_param] PLL: p=%d, r=%d, j=%d, d=%d, fsref=%d\n\n", pll_p, pll_r, pll_j, pll_d, fsref);
snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_OVRF_STATUS_AND_PLLR_REG=%d\n\n", pll_r << PLLR_SHIFT);
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGB_REG=%d\n\n", pll_j << PLLJ_SHIFT);
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGC_REG=%d\n\n", (pll_d >> 6) << PLLD_MSB_SHIFT);
+ printk(KERN_ERR "[CTTest-hw_param] AIC3X_PLL_PROGD_REG=%d\n\n", (pll_d & 0x3F) << PLLD_LSB_SHIFT);
snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
pll_r << PLLR_SHIFT);
snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
@@ -1165,7 +1197,7 @@ found:
(pll_d >> 6) << PLLD_MSB_SHIFT);
snd_soc_write(codec, AIC3X_PLL_PROGD_REG,
(pll_d & 0x3F) << PLLD_LSB_SHIFT);
-
+#endif
return 0;
}
@@ -1188,7 +1220,7 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
/* Configure data delay */
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
-
+ printk(KERN_ERR "[CTTest] AIC3X_ASD_INTF_CTRLC:%d\n\n", snd_soc_read(codec, AIC3X_ASD_INTF_CTRLC));
return 0;
}
@@ -1197,7 +1229,7 @@ static int aic3x_mute(struct snd_soc_dai *dai, int mute)
struct snd_soc_codec *codec = dai->codec;
u8 ldac_reg = snd_soc_read(codec, LDAC_VOL) & ~MUTE_ON;
u8 rdac_reg = snd_soc_read(codec, RDAC_VOL) & ~MUTE_ON;
-
+ printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s : %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__, mute?"Yes":"No");
if (mute) {
snd_soc_write(codec, LDAC_VOL, ldac_reg | MUTE_ON);
snd_soc_write(codec, RDAC_VOL, rdac_reg | MUTE_ON);
@@ -1214,13 +1246,13 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{
struct snd_soc_codec *codec = codec_dai->codec;
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-
/* set clock on MCLK or GPIO2 or BCLK */
- snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
- clk_id << PLLCLK_IN_SHIFT);
- snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
- clk_id << CLKDIV_IN_SHIFT);
-
+ snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
+ clk_id << PLLCLK_IN_SHIFT);
+ snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
+ clk_id << CLKDIV_IN_SHIFT);
+ printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s : freq=%d, AIC3X_CLKGEN_CTRL_REG=%d!!!!!!!!!!!!!!!!!!\n\n\n\n",
+ __func__, freq, snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG));
aic3x->sysclk = freq;
return 0;
}
@@ -1231,7 +1263,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec;
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
u8 iface_areg, iface_breg;
-
+ printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__);
iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
@@ -1245,6 +1277,16 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
aic3x->master = 0;
iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ aic3x->master = 1;
+ iface_areg |= BIT_CLK_MASTER;
+ iface_areg &= ~WORD_CLK_MASTER;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ aic3x->master = 1;
+ iface_areg |= WORD_CLK_MASTER;
+ iface_areg &= ~BIT_CLK_MASTER;
+ break;
default:
return -EINVAL;
}
@@ -1276,7 +1318,8 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* set iface */
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
-
+ printk(KERN_ERR "[CTTest-fmt] AIC3X_ASD_INTF_CTRLA:%d\n\n", iface_areg);
+ printk(KERN_ERR "[CTTest-fmt] AIC3X_ASD_INTF_CTRLB:%d\n\n", iface_breg);
return 0;
}
@@ -1380,6 +1423,12 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c);
snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d);
}
+
+ /*
+ * Delay is needed to reduce pop-noise after syncing back the
+ * registers
+ */
+ mdelay(50);
} else {
/*
* Do soft reset to this codec instance in order to clear
@@ -1553,6 +1602,10 @@ static int aic3x_init(struct snd_soc_codec *codec)
break;
}
+ /* Output common-mode voltage = 1.5 V */
+ snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK,
+ aic3x->ocmv << HPOUT_SC_OCMV_SHIFT);
+
return 0;
}
@@ -1571,10 +1624,20 @@ static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
static int aic3x_probe(struct snd_soc_codec *codec)
{
+ printk(KERN_ERR "!!!!!!!!!!!!!!!!!!! %s !!!!!!!!!!!!!!!!!!\n\n\n\n", __func__);
+
+
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int ret, i;
+ u32 tmp_reg;
+
+ if (gpio_is_valid(aic3x->gpio_reset)) {
+ ndelay(10);
+ tmp_reg = gpio_get_value(aic3x->gpio_reset);
+ gpio_set_value(aic3x->gpio_reset, 1);
+ printk(KERN_ERR "[CTTest] gpio reset:%d to %d\n\n", tmp_reg, gpio_get_value(aic3x->gpio_reset));
+ }
- INIT_LIST_HEAD(&aic3x->list);
aic3x->codec = codec;
for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
@@ -1586,7 +1649,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
dev_err(codec->dev,
"Failed to request regulator notifier: %d\n",
ret);
- goto err_notif;
+ return ret;
}
}
@@ -1640,27 +1703,73 @@ static int aic3x_probe(struct snd_soc_codec *codec)
*/
break;
}
+#if 1
+ snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, 0x0);
+
+ //Bit clock of data offset before the valid data
+ tmp_reg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLC);
+ snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, 0x1);
+ printk(KERN_ERR "[CTTest] AIC3X_ASD_INTF_CTRLC:%d to %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_ASD_INTF_CTRLC));
+
+ //CLK source settings for PLLCLK_IN and CLKDIV_IN
+ tmp_reg = snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG);
+ tmp_reg = (tmp_reg & ~0xff) | 0x02;
+ snd_soc_write(codec, AIC3X_CLKGEN_CTRL_REG, tmp_reg);
+ printk(KERN_ERR "[CTTest] AIC3X_CLKGEN_CTRL_REG:%d = %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_CLKGEN_CTRL_REG));
+
+#if 0
+ //PLL settings
+ tmp_reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
+ tmp_reg = (tmp_reg & (~0xff)) | 0x92;
+ snd_soc_write(codec, AIC3X_PLL_PROGA_REG, tmp_reg);
+ printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGA_REG:%d = %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_PLL_PROGA_REG));
+ snd_soc_write(codec, AIC3X_PLL_PROGB_REG, 0x7 << 2);
+ printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGB_REG:%d = %d\n\n", 0x7 << 2, snd_soc_read(codec, AIC3X_PLL_PROGB_REG));
+
+ snd_soc_write(codec, AIC3X_PLL_PROGC_REG, 0x52);
+ printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGC_REG:%d = %d\n\n", 0x82, snd_soc_read(codec, AIC3X_PLL_PROGC_REG));
+ snd_soc_write(codec, AIC3X_PLL_PROGD_REG, 0x40);
+ printk(KERN_ERR "[CTTest] AIC3X_PLL_PROGD_REG:%d = %d\n\n", 0x10, snd_soc_read(codec, AIC3X_PLL_PROGD_REG));
+#endif
- aic3x_add_widgets(codec);
+ //Connect DAC to output HPLOUT and HPLCOM
+ tmp_reg = snd_soc_read(codec, DACL1_2_HPLOUT_VOL);
+ snd_soc_update_bits(codec, DACL1_2_HPLOUT_VOL, ROUTE_ON, ROUTE_ON);
+ printk(KERN_ERR "[CTTest] reg47 DACL1_2_HPLOUT_VOL:%d to %d\n\n", tmp_reg, snd_soc_read(codec, DACL1_2_HPLOUT_VOL));
+ tmp_reg = snd_soc_read(codec, DACL1_2_HPLCOM_VOL);
+ snd_soc_update_bits(codec, DACL1_2_HPLCOM_VOL, ROUTE_ON, ROUTE_ON);
+ printk(KERN_ERR "[CTTest] reg54 DACL1_2_HPLCOM_VOL:%d to %d\n\n", tmp_reg, snd_soc_read(codec, DACL1_2_HPLCOM_VOL));
- return 0;
+ //Umute
+ snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
+ printk(KERN_ERR "[CTTest] HPLOUT_CTRL:%d = %d\n\n", UNMUTE, snd_soc_read(codec, HPLOUT_CTRL));
+ snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
+ printk(KERN_ERR "[CTTest] HPLCOM_CTRL:%d = %d\n\n", UNMUTE, snd_soc_read(codec, HPLCOM_CTRL));
-err_notif:
- while (i--)
- regulator_unregister_notifier(aic3x->supplies[i].consumer,
- &aic3x->disable_nb[i].nb);
- return ret;
-}
+ tmp_reg = snd_soc_read(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG);
+ //snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, 0x0);
+ printk(KERN_ERR "[CTTest] AIC3X_OVRF_STATUS_AND_PLLR_REG:%d = %d\n\n", tmp_reg, snd_soc_read(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG));
+ /* Route Left DAC to left channel input and
+ * right DAC to right channel input */
+ //snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, 0x8a);
+ printk(KERN_ERR "[CTTest] AIC3X_CODEC_DATAPATH_REG:%d = %d\n\n", 0x8a, snd_soc_read(codec, AIC3X_CODEC_DATAPATH_REG));
-static int aic3x_remove(struct snd_soc_codec *codec)
-{
- struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
- int i;
+ //snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, 0x0);
+ printk(KERN_ERR "[CTTest] AIC3X_SAMPLE_RATE_SEL_REG:%d = %d\n\n", 0x0, snd_soc_read(codec, AIC3X_SAMPLE_RATE_SEL_REG));
- list_del(&aic3x->list);
- for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
- regulator_unregister_notifier(aic3x->supplies[i].consumer,
- &aic3x->disable_nb[i].nb);
+#endif
+
+ //DAC power setting
+ snd_soc_write(codec, DAC_PWR, 0xC0);
+ printk(KERN_ERR "[CTTest] DAC_PWR:%d = %d\n\n", 0xC0, snd_soc_read(codec, DAC_PWR));
+
+ //HPLOUT and HPLCOM power setting
+ snd_soc_update_bits(codec, HPLOUT_CTRL, HPLOUT_PWR_ON, HPLOUT_PWR_ON);
+ printk(KERN_ERR "[CTTest] HPLOUT_CTRL:%d = %d\n\n", HPLOUT_PWR_ON, snd_soc_read(codec, HPLOUT_CTRL));
+ snd_soc_update_bits(codec, HPLCOM_CTRL, HPLCOM_PWR_ON, HPLCOM_PWR_ON);
+ printk(KERN_ERR "[CTTest] HPLCOM_CTRL:%d = %d\n\n", HPLCOM_PWR_ON, snd_soc_read(codec, HPLCOM_CTRL));
+
+ aic3x_add_widgets(codec);
return 0;
}
@@ -1669,7 +1778,6 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
.set_bias_level = aic3x_set_bias_level,
.idle_bias_off = true,
.probe = aic3x_probe,
- .remove = aic3x_remove,
.controls = aic3x_snd_controls,
.num_controls = ARRAY_SIZE(aic3x_snd_controls),
.dapm_widgets = aic3x_dapm_widgets,
@@ -1678,6 +1786,44 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
.num_dapm_routes = ARRAY_SIZE(intercon),
};
+static void aic3x_configure_ocmv(struct i2c_client *client)
+{
+ struct device_node *np = client->dev.of_node;
+ struct aic3x_priv *aic3x = i2c_get_clientdata(client);
+ u32 value;
+ int dvdd, avdd;
+
+ if (np && !of_property_read_u32(np, "ai3x-ocmv", &value)) {
+ /* OCMV setting is forced by DT */
+ if (value <= 3) {
+ aic3x->ocmv = value;
+ return;
+ }
+ }
+
+ dvdd = regulator_get_voltage(aic3x->supplies[1].consumer);
+ avdd = regulator_get_voltage(aic3x->supplies[2].consumer);
+
+ if (avdd > 3600000 || dvdd > 1950000) {
+ dev_warn(&client->dev,
+ "Too high supply voltage(s) AVDD: %d, DVDD: %d\n",
+ avdd, dvdd);
+ } else if (avdd == 3600000 && dvdd == 1950000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_8V;
+ } else if (avdd > 3300000 && dvdd > 1800000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_65V;
+ } else if (avdd > 3000000 && dvdd > 1650000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_5V;
+ } else if (avdd >= 2700000 && dvdd >= 1525000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_35V;
+ } else {
+ dev_warn(&client->dev,
+ "Invalid supply voltage(s) AVDD: %d, DVDD: %d\n",
+ avdd, dvdd);
+ }
+}
+
+
/*
* AIC3X 2 wire address can be up to 4 devices with device addresses
* 0x18, 0x19, 0x1A, 0x1B
@@ -1717,6 +1863,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
int ret, i;
u32 value;
+ dev_err(&i2c->dev, "!!!!!!!!!!!!!! aic3x_i2c_probe !!!!!!!!!!!!!!!!!\n\n\n\n");
+
aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
if (!aic3x)
return -ENOMEM;
@@ -1740,11 +1888,18 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
if (!ai3x_setup)
return -ENOMEM;
- ret = of_get_named_gpio(np, "gpio-reset", 0);
- if (ret >= 0)
+ ret = of_get_named_gpio(np, "reset-gpios", 0);
+ if (ret >= 0) {
aic3x->gpio_reset = ret;
- else
- aic3x->gpio_reset = -1;
+ } else {
+ ret = of_get_named_gpio(np, "gpio-reset", 0);
+ if (ret > 0) {
+ dev_warn(&i2c->dev, "Using deprecated property \"gpio-reset\", please update your DT");
+ aic3x->gpio_reset = ret;
+ } else {
+ aic3x->gpio_reset = -1;
+ }
+ }
if (of_property_read_u32_array(np, "ai3x-gpio-func",
ai3x_setup->gpio_func, 2) >= 0) {
@@ -1795,6 +1950,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
goto err_gpio;
}
+ aic3x_configure_ocmv(i2c);
+
if (aic3x->model == AIC3X_MODEL_3007) {
ret = regmap_register_patch(aic3x->regmap, aic3007_class_d,
ARRAY_SIZE(aic3007_class_d));
@@ -1809,6 +1966,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
if (ret != 0)
goto err_gpio;
+ INIT_LIST_HEAD(&aic3x->list);
list_add(&aic3x->list, &reset_list);
return 0;
@@ -1825,7 +1983,8 @@ static int aic3x_i2c_remove(struct i2c_client *client)
{
struct aic3x_priv *aic3x = i2c_get_clientdata(client);
- snd_soc_unregister_codec(&client->dev);
+ list_del(&aic3x->list);
+
if (gpio_is_valid(aic3x->gpio_reset) &&
!aic3x_is_shared_reset(aic3x)) {
gpio_set_value(aic3x->gpio_reset, 0);
- tegra_t186ref_mobile_rt565x.c
diff --git a/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c b/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
index ebd6702..8eada05 100644
--- a/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
+++ b/kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x.c
@@ -44,7 +44,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../codecs/rt5659.h"
-
+#include "../codecs/tlv320aic3x.h"
#include "tegra_asoc_utils_alt.h"
#include "tegra_asoc_machine_alt.h"
#include "tegra_asoc_machine_alt_t18x.h"
@@ -69,7 +69,7 @@
.channels_min = channels, \
.channels_max = channels, \
}
-
+
struct tegra_t186ref {
struct tegra_asoc_platform_data *pdata;
struct tegra_asoc_audio_clock_info audio_clock;
@@ -132,7 +132,9 @@ static int tegra_t186ref_jack_notifier(struct notifier_block *self,
idx = tegra_machine_get_codec_dai_link_idx_t18x("rt565x-playback");
/* check if idx has valid number */
if (idx == -EINVAL)
+ {
return idx;
+ }
dev_dbg(card->dev, "jack status = %d", jack->status);
if (jack->status & (SND_JACK_BTN_0 | SND_JACK_BTN_1 |
@@ -277,6 +279,8 @@ static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
unsigned int idx, clk_out_rate;
int err, codec_rate, clk_rate;
+ dev_err(card->dev, "[CTTest] rate = %d Hz, formats = %llx, is_playback = %d, machine->rate_via_kcontrol=%d\n",
+ rate, formats, is_playback, machine->rate_via_kcontrol);
codec_rate = tegra_t186ref_srate_values[machine->rate_via_kcontrol];
clk_rate = (machine->rate_via_kcontrol) ? codec_rate : rate;
@@ -289,12 +293,13 @@ static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
clk_out_rate = machine->audio_clock.clk_out_rate;
- pr_debug("pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
+ pr_debug("[CTTest] pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
+ machine->audio_clock.set_mclk, clk_out_rate, clk_rate);
+ dev_err(card->dev, "[CTTest] pll_a_out0 = %d Hz, aud_mclk = %d Hz, codec rate = %d Hz\n",
machine->audio_clock.set_mclk, clk_out_rate, clk_rate);
-
tegra_t186ref_set_params(card, machine, rate, channels, formats);
- idx = tegra_machine_get_codec_dai_link_idx_t18x("rt565x-playback");
+ idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback");
/* check if idx has valid number */
if (idx != -EINVAL) {
dai_params =
@@ -306,83 +311,14 @@ static int tegra_t186ref_dai_init(struct snd_soc_pcm_runtime *rtd,
if (!machine->is_codec_dummy) {
err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
- RT5659_SCLK_S_MCLK, clk_out_rate, SND_SOC_CLOCK_IN);
+ 0, 12000000, SND_SOC_CLOCK_IN);
if (err < 0) {
- dev_err(card->dev, "codec_dai clock not set\n");
+ dev_err(card->dev, "[ti-playback] codec_dai clock not set\n");
return err;
}
- }
- }
-
- /* set clk rate for i2s3 dai link*/
- idx = tegra_machine_get_codec_dai_link_idx_t18x("spdif-dit-2");
- if (idx != -EINVAL) {
- dai_params =
- (struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
- dai_params->rate_min = clk_rate;
- }
-
- idx = tegra_machine_get_codec_dai_link_idx_t18x("dspk-playback-r");
- if (idx != -EINVAL) {
- dai_params =
- (struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
- if (!machine->is_codec_dummy) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
- err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
- 0, clk_out_rate, SND_SOC_CLOCK_IN);
-#else
- err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
- TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
- SND_SOC_CLOCK_IN);
-#endif
- if (err < 0) {
- dev_err(card->dev, "codec_dai clock not set\n");
- return err;
- }
- }
- }
-
- idx = tegra_machine_get_codec_dai_link_idx_t18x("dspk-playback-l");
- if (idx != -EINVAL) {
- dai_params =
- (struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
- if (!machine->is_codec_dummy) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
- err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
- 0, clk_out_rate, SND_SOC_CLOCK_IN);
-#else
- err = snd_soc_dai_set_sysclk(card->rtd[idx].codec_dai,
- TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
- SND_SOC_CLOCK_IN);
-#endif
- if (err < 0) {
- dev_err(card->dev, "codec_dai clock not set\n");
- return err;
- }
- }
- }
-
- idx = tegra_machine_get_codec_dai_link_idx_t18x("spdif-playback");
- if ((idx != -EINVAL) && (clk_rate >= 32000)) {
- dai_params =
- (struct snd_soc_pcm_stream *)card->rtd[idx].dai_link->params;
-
- if (is_playback) {
- err = snd_soc_dai_set_sysclk(card->rtd[idx].cpu_dai, 0,
- clk_rate, SND_SOC_CLOCK_OUT);
- if (err < 0) {
- dev_err(card->dev, "cpu_dai out clock not set\n");
- return err;
- }
- } else {
- err = snd_soc_dai_set_sysclk(card->rtd[idx].cpu_dai, 0,
- clk_rate, SND_SOC_CLOCK_IN);
- if (err < 0) {
- dev_err(card->dev, "cpu_dai in clock not set\n");
- return err;
+ else
+ {
+ dev_err(card->dev, "[ti-playback] codec_dai clock set at id %d \n", idx);
}
}
}
@@ -399,9 +335,15 @@ static int tegra_t186ref_hw_params(struct snd_pcm_substream *substream,
bool is_playback;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ {
+ dev_err(card->dev, "tegra_t186ref_hw_params: set Playback\n");
is_playback = true;
+ }
else
+ {
+ dev_err(card->dev, "tegra_t186ref_hw_params: not set Playback\n");
is_playback = false;
+ }
err = tegra_t186ref_dai_init(rtd, params_rate(params),
params_channels(params),
@@ -460,16 +402,15 @@ static int tegra_t186ref_dspk_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct snd_soc_dapm_context *dapm = &card->dapm;
- struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
- int err;
-
+ //struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
+#if 0 //request by Jon
err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
"pll_a_out0");
if (err < 0)
dev_err(card->dev, "Failed to set extern clk parent\n");
-
+#endif
snd_soc_dapm_sync(dapm);
- return err;
+ return 0;
}
static int tegra_t186ref_compr_set_params(struct snd_compr_stream *cstream)
@@ -513,20 +454,20 @@ static int tegra_t186ref_compr_set_params(struct snd_compr_stream *cstream)
static int tegra_t186ref_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
- struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
+ //struct tegra_t186ref *machine = snd_soc_card_get_drvdata(card);
int err;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_codec *codec = codec_dai->codec;
#endif
-
+#if 0 //request by Jon
err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
"pll_a_out0");
if (err < 0) {
dev_err(card->dev, "Failed to set extern clk parent\n");
return err;
}
-
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
&tegra_t186ref_hp_jack);
@@ -708,6 +649,8 @@ static const struct snd_soc_dapm_widget tegra_t186ref_dapm_widgets[] = {
SND_SOC_DAPM_MIC("e Mic", NULL),
SND_SOC_DAPM_SPK("d1 Headphone", NULL),
SND_SOC_DAPM_SPK("d2 Headphone", NULL),
+ SND_SOC_DAPM_LINE( "z IN", NULL),
+ SND_SOC_DAPM_LINE( "z OUT", NULL),
};
static int tegra_t186ref_suspend_pre(struct snd_soc_card *card)
@@ -933,6 +876,8 @@ static void dai_link_setup(struct platform_device *pdev)
if (strstr(tegra_t186ref_codec_links[i].name,
"rt565x-playback"))
tegra_t186ref_codec_links[i].init = tegra_t186ref_init;
+ else if (strstr(tegra_t186ref_codec_links[i].name, "ti-playback"))
+ tegra_t186ref_codec_links[i].init = tegra_t186ref_init;
else if (strstr(tegra_t186ref_codec_links[i].name,
"dspk-playback-r"))
tegra_t186ref_codec_links[i].init = tegra_t186ref_dspk_init;
@@ -1018,9 +963,9 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
struct snd_soc_card *card = &snd_soc_tegra_t186ref;
struct tegra_t186ref *machine;
struct tegra_asoc_platform_data *pdata = NULL;
+ int ret = 0;
struct snd_soc_codec *codec = NULL;
int idx = 0;
- int ret = 0;
const char *codec_dai_name;
if (!np) {
@@ -1103,6 +1048,14 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
if (ret)
goto err_switch_unregister;
+ ret = tegra_alt_asoc_utils_set_parent(&machine->audio_clock, false);
+ if (ret)
+ {
+ dev_err(&pdev->dev, "tegra_alt_asoc_utils_set_parent failed (%d)\n",
+ ret);
+ goto err_switch_unregister;
+ }
+
ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
@@ -1110,7 +1063,7 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
goto err_fini_utils;
}
- idx = tegra_machine_get_codec_dai_link_idx_t18x("rt565x-playback");
+ idx = tegra_machine_get_codec_dai_link_idx_t18x("ti-playback");
/* check if idx has valid number */
if (idx == -EINVAL)
dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card");
@@ -1120,6 +1073,7 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
dev_info(&pdev->dev,
"codec-dai \"%s\" registered\n", codec_dai_name);
+ #if 0
if (!strcmp("dit-hifi", codec_dai_name)) {
dev_info(&pdev->dev, "This is a dummy codec\n");
machine->is_codec_dummy = 1;
@@ -1129,8 +1083,10 @@ static int tegra_t186ref_driver_probe(struct platform_device *pdev)
/* setup for jack detection only in non-dummy case */
rt5659_set_jack_detect(codec, &tegra_t186ref_hp_jack);
}
+ #endif
}
+
return 0;
err_fini_utils:
- tegra_asoc_utils_alt.c
diff --git a/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c b/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c
index 92418bc..9f20202 100644
--- a/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c
+++ b/kernel/kernel-4.4/sound/soc/tegra-alt/tegra_asoc_utils_alt.c
@@ -160,6 +160,8 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
bool clk_change;
int err;
+ dev_err(data->dev, "[CTTest] alt asoc set rate, argument, srate = %d, mclk=%d, clk_out_rate=%d, data->mclk_scale=%d\n",
+ srate, mclk, clk_out_rate, data->mclk_scale);
switch (srate) {
case 11025:
case 22050:
@@ -259,17 +261,19 @@ int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
return err;
}
}
-
+#if 0
err = clk_set_rate(data->clk_cdev1, clk_out_rate);
if (err) {
dev_err(data->dev, "Can't set clk_cdev1 rate: %d\n", err);
return err;
}
-
+#endif
data->set_baseclock = new_baseclock;
data->set_mclk = mclk;
data->set_clk_out_rate = clk_out_rate;
+ dev_err(data->dev, "[CTTest] alt asoc set rate, set_mclk=%d, set_clk_out_rate=%d, set_baseclock=%d\n",
+ mclk, clk_out_rate, new_baseclock);
return 0;
}
EXPORT_SYMBOL_GPL(tegra_alt_asoc_utils_set_rate);
@@ -353,6 +357,7 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
return -EINVAL;
/* pll_p_out1 is not used for ahub for T210,T186 */
+ #if 0
if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) {
data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1");
if (IS_ERR(data->clk_pll_p_out1)) {
@@ -361,6 +366,14 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
goto err;
}
}
+ #else
+ data->clk_pll_p_out1 = tegra_alt_asoc_utils_get_clk(dev, false, "pll_p_out1");
+ if (IS_ERR(data->clk_pll_p_out1)) {
+ dev_err(data->dev, "Can't retrieve clk pll_p_out1\n");
+ ret = PTR_ERR(data->clk_pll_p_out1);
+ goto err;
+ }
+ #endif
data->clk_m = tegra_alt_asoc_utils_get_clk(dev, false, "clk_m");
if (IS_ERR(data->clk_m)) {
@@ -418,6 +431,8 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
#endif
}
+ dev_err(dev, "[CTTest] A-set clk, set_mclk=%d, clk_out_rate=%d\n",
+ data->set_mclk, data->clk_out_rate);
if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210) {
ret = tegra_alt_asoc_utils_set_rate(data, 48000,
256 * 48000, 256 * 48000);
@@ -425,6 +440,9 @@ int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
goto err_put_ahub;
}
+
+ dev_err(dev, "[CTTest] B-set clk, set_mclk=%d, clk_out_rate=%d\n",
+ data->set_mclk, data->clk_out_rate);
#if !defined(CONFIG_ARCH_TEGRA_18x_SOC)
ret = clk_prepare_enable(data->clk_cdev1);
if (ret) {
@@ -445,7 +463,7 @@ err_put_pll_a_out0:
err_put_pll_a:
tegra_alt_asoc_utils_clk_put(dev, data->clk_pll_a);
err_put_pll_p_out1:
- if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
+ //if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
clk_put(data->clk_pll_p_out1);
err:
return ret;
@@ -467,13 +485,14 @@ int tegra_alt_asoc_utils_set_parent(struct tegra_asoc_audio_clock_info *data,
return ret;
}
} else {
- ret = clk_set_parent(data->clk_cdev1, data->clk_m);
+ ret = clk_set_parent(data->clk_cdev1, data->clk_pll_p_out1);
if (ret) {
dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
return ret;
}
- ret = clk_set_rate(data->clk_cdev1, 13000000);
+ //ret = clk_set_rate(data->clk_cdev1, 13000000);
+ ret = clk_set_rate(data->clk_cdev1, 12000000);
if (ret) {
dev_err(data->dev, "Can't set clk rate");
return ret;
@@ -533,7 +552,7 @@ void tegra_alt_asoc_utils_fini(struct tegra_asoc_audio_clock_info *data)
if (!IS_ERR(data->clk_pll_a))
tegra_alt_asoc_utils_clk_put(data->dev, data->clk_pll_a);
- if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
+ //if (data->soc < TEGRA_ASOC_UTILS_SOC_TEGRA210)
if (!IS_ERR(data->clk_pll_p_out1))
clk_put(data->clk_pll_p_out1);
}
Do I miss some settings?
Thanks,
C.T.