Hi,WayneWWW.
The following code is modified
tlv320aic32x4.c
static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
//SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0), //modify 2019.8.24
SND_SOC_DAPM_DAC("Left DAC", "Playback", AIC32X4_DACSETUP, 7, 0),
SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
&hpl_output_mixer_controls[0],
ARRAY_SIZE(hpl_output_mixer_controls)),
SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
&lol_output_mixer_controls[0],
ARRAY_SIZE(lol_output_mixer_controls)),
SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),
//SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0), //modify 2019.8.24
SND_SOC_DAPM_DAC("Right DAC", "Playback", AIC32X4_DACSETUP, 6, 0),
SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
&hpr_output_mixer_controls[0],
ARRAY_SIZE(hpr_output_mixer_controls)),
SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
&lor_output_mixer_controls[0],
ARRAY_SIZE(lor_output_mixer_controls)),
SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
//SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0), //modify 2019.8.24
SND_SOC_DAPM_ADC("Right ADC", "Capture", AIC32X4_ADCSETUP, 6, 0),
SND_SOC_DAPM_MUX("IN1_R to Right Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in1r_to_rmixer_controls),
SND_SOC_DAPM_MUX("IN2_R to Right Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in2r_to_rmixer_controls),
SND_SOC_DAPM_MUX("IN3_R to Right Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in3r_to_rmixer_controls),
SND_SOC_DAPM_MUX("IN2_L to Right Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in2l_to_rmixer_controls),
SND_SOC_DAPM_MUX("CM_R to Right Mixer Negative Resistor", SND_SOC_NOPM, 0, 0,
cmr_to_rmixer_controls),
SND_SOC_DAPM_MUX("IN1_L to Right Mixer Negative Resistor", SND_SOC_NOPM, 0, 0,
in1l_to_rmixer_controls),
SND_SOC_DAPM_MUX("IN3_L to Right Mixer Negative Resistor", SND_SOC_NOPM, 0, 0,
in3l_to_rmixer_controls),
//SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0), //modify 2019.8.24
SND_SOC_DAPM_ADC("Left ADC", "Capture", AIC32X4_ADCSETUP, 7, 0),
SND_SOC_DAPM_MUX("IN1_L to Left Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in1l_to_lmixer_controls),
SND_SOC_DAPM_MUX("IN2_L to Left Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in2l_to_lmixer_controls),
SND_SOC_DAPM_MUX("IN3_L to Left Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in3l_to_lmixer_controls),
SND_SOC_DAPM_MUX("IN1_R to Left Mixer Positive Resistor", SND_SOC_NOPM, 0, 0,
in1r_to_lmixer_controls),
SND_SOC_DAPM_MUX("CM_L to Left Mixer Negative Resistor", SND_SOC_NOPM, 0, 0,
cml_to_lmixer_controls),
SND_SOC_DAPM_MUX("IN2_R to Left Mixer Negative Resistor", SND_SOC_NOPM, 0, 0,
in2r_to_lmixer_controls),
SND_SOC_DAPM_MUX("IN3_R to Left Mixer Negative Resistor", SND_SOC_NOPM, 0, 0,
in3r_to_lmixer_controls),
SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0),
SND_SOC_DAPM_OUTPUT("HPL"),
SND_SOC_DAPM_OUTPUT("HPR"),
SND_SOC_DAPM_OUTPUT("LOL"),
SND_SOC_DAPM_OUTPUT("LOR"),
SND_SOC_DAPM_INPUT("IN1_L"),
SND_SOC_DAPM_INPUT("IN1_R"),
SND_SOC_DAPM_INPUT("IN2_L"),
SND_SOC_DAPM_INPUT("IN2_R"),
SND_SOC_DAPM_INPUT("IN3_L"),
SND_SOC_DAPM_INPUT("IN3_R"),
};
static const struct regmap_range_cfg aic32x4_regmap_pages[] = {
{
.selector_reg = 0,
.selector_mask = 0xff,
.window_start = 0,
.window_len = 128,
.range_min = 0,
.range_max = 0xFB,
//.range_max = AIC32X4_RMICPGAVOL, //modify 2019.8.24
},
};
const struct regmap_config aic32x4_regmap_config = {
//.max_register = AIC32X4_RMICPGAVOL, //modify 2019.8.24
.max_register = 0xFB,
.ranges = aic32x4_regmap_pages,
.num_ranges = ARRAY_SIZE(aic32x4_regmap_pages),
};
static int aic32x4_codec_probe(struct snd_soc_codec *codec)
{
struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
u32 tmp_reg;
printk(KERN_ERR "aic32x4:===========probe===============");//add 2019.8.24
if (gpio_is_valid(aic32x4->rstn_gpio)) {
ndelay(10);
gpio_set_value(aic32x4->rstn_gpio, 1);
}
snd_soc_write(codec, AIC32X4_RESET, 0x01);
/* Power platform configuration */
if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
AIC32X4_MICBIAS_2075V);
}
if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
AIC32X4_LDOCTLEN : 0;
snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);
tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36)
tmp_reg |= AIC32X4_LDOIN_18_36;
if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED)
tmp_reg |= AIC32X4_LDOIN2HP;
snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
/* Mic PGA routing */
if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K)
snd_soc_write(codec, AIC32X4_LMICPGANIN,
AIC32X4_LMICPGANIN_IN2R_10K);
else
snd_soc_write(codec, AIC32X4_LMICPGANIN,
AIC32X4_LMICPGANIN_CM1L_10K);
if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K)
snd_soc_write(codec, AIC32X4_RMICPGANIN,
AIC32X4_RMICPGANIN_IN1L_10K);
else
snd_soc_write(codec, AIC32X4_RMICPGANIN,
AIC32X4_RMICPGANIN_CM1R_10K);
/*
* Workaround: for an unknown reason, the ADC needs to be powered up
* and down for the first capture to work properly. It seems related to
* a HW BUG or some kind of behavior not documented in the datasheet.
*/
tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP);
snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg |
AIC32X4_LADC_EN | AIC32X4_RADC_EN);
snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg);
#if 0 //add 2019.8.24
snd_soc_write(codec, AIC32X4_CLKMUX, 0x07);
snd_soc_write(codec, AIC32X4_PLLPR, 0x92);
snd_soc_write(codec, AIC32X4_PLLJ, 0x20);
snd_soc_write(codec, AIC32X4_PLLDMSB, 0x00);
snd_soc_write(codec, AIC32X4_PLLDLSB, 0x00);
snd_soc_write(codec, AIC32X4_NADC, 0x84);
snd_soc_write(codec, AIC32X4_MADC, 0x84);
snd_soc_write(codec, AIC32X4_AOSR, 0x80);
snd_soc_write(codec, AIC32X4_DOSRLSB, 0x80);
snd_soc_write(codec, AIC32X4_DOSRMSB, 0x00);
snd_soc_write(codec, AIC32X4_DACSETUP, 0xD4);
snd_soc_write(codec, AIC32X4_LOLROUTE, 0x08);
snd_soc_write(codec, AIC32X4_LORROUTE, 0x08);
snd_soc_write(codec, AIC32X4_LOLGAIN, 0x1D);
snd_soc_write(codec, AIC32X4_LORGAIN, 0x1D);
snd_soc_write(codec, AIC32X4_LDACVOL, 0xB3);
snd_soc_write(codec, AIC32X4_RDACVOL, 0xB3);
snd_soc_write(codec, AIC32X4_LMICPGAPIN, 0x00);
snd_soc_write(codec, AIC32X4_LMICPGANIN, 0x10);
snd_soc_write(codec, AIC32X4_RMICPGAPIN, 0x10);
snd_soc_write(codec, AIC32X4_RMICPGANIN, 0x40);
snd_soc_write(codec, AIC32X4_LMICPGAVOL, 0x5A);
snd_soc_write(codec, AIC32X4_RMICPGAVOL, 0x5A);
snd_soc_write(codec, AIC32X4_ADCSETUP, 0xC0);
snd_soc_write(codec, AIC32X4_ADCFGA, 0x00);
snd_soc_write(codec, AIC32X4_PWRCFG, 0x08);
snd_soc_write(codec, AIC32X4_LDOCTL, 0x01);
snd_soc_write(codec, 0xFB, 0x01);
snd_soc_write(codec, AIC32X4_CMMODE, 0x00);
snd_soc_write(codec, 0x98, 0x28);
snd_soc_write(codec, AIC32X4_OUTPWRCTL, 0x0C);
#endif
return 0;
}
tegra_machine_driver_mobile.c
static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
int rate,
int channels,
u64 formats,
bool is_playback)
{
struct snd_soc_card *card = runtime->card;
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
struct snd_soc_pcm_stream *dai_params;
unsigned int clk_out_rate = 0, mclk = 0;
int err, codec_rate, clk_rate;
struct snd_soc_pcm_runtime *rtd;
codec_rate = tegra_machine_srate_values[machine->rate_via_kcontrol];
clk_rate = (machine->rate_via_kcontrol) ? codec_rate : rate;
if (!machine->soc_data->is_clk_rate_via_dt) {
/* TODO remove this hardcoding */
/* aud_mclk, 256 times the sample rate */
clk_out_rate = clk_rate << 8;
switch (clk_rate) {
case 11025:
mclk = 22579200;
break;
case 22050:
case 44100:
case 88200:
case 176400:
mclk = 45158400;
break;
case 8000:
mclk = 24576000;
break;
case 16000:
case 32000:
case 48000:
case 64000:
case 96000:
case 192000:
default:
mclk = 49152000;
break;
}
err = tegra210_xbar_set_clock(mclk);
if (err < 0) {
dev_err(card->dev,
"Can't configure xbar clock = %d Hz\n", mclk);
return err;
}
}
err = tegra_alt_asoc_utils_set_rate(&machine->audio_clock, clk_rate,
mclk, clk_out_rate);
if (err < 0) {
dev_err(card->dev, "Can't configure clocks\n");
return err;
}
if (machine->soc_data->is_clk_rate_via_dt)
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",
machine->audio_clock.set_mclk, clk_out_rate, clk_rate);
/* TODO: should we pass here clk_rate ? */
err = tegra_machine_set_params(card, machine, rate, channels, formats);
if (err < 0)
return err;
#if 0
//add sound card 2019.8.24
rtd = snd_soc_get_pcm_runtime(card, "ti-playback-i2s1");
printk(KERN_ERR "tegra_machine_dai_init:====ti-playback-i2s1-rtd =====\n");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
if (machine->is_hs_supported) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
0, 12000000, SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
}
}
rtd = snd_soc_get_pcm_runtime(card, "ti-playback-i2s2");
printk(KERN_ERR "tegra_machine_dai_init:====ti-playback-i2s2-rtd =====\n");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
if (machine->is_hs_supported) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
0, 12000000, SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
}
}
#else //modify 2019.8.24
rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
if (machine->is_hs_supported) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
RT5659_SCLK_S_MCLK, clk_out_rate, SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
}
}
rtd = snd_soc_get_pcm_runtime(card, "rt565x-codec-sysclk-bclk1");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
err = rt565x_manage_codec_sysclk(dai_params, rtd->codec_dai,
RT5659_PLL1_S_BCLK1);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
}
/* TODO: remove below spdif links if clk_rate is passed
* in tegra_machine_set_params
*/
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-1");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
}
/* set clk rate for i2s3 dai link*/
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-2");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
}
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-3");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
dai_params->rate_min = clk_rate;
}
rtd = snd_soc_get_pcm_runtime(card, "spdif-dit-5");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
/* update link_param to update hw_param for DAPM */
dai_params->rate_min = clk_rate;
dai_params->channels_min = channels;
dai_params->formats = formats;
}
rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-r");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
}
}
rtd = snd_soc_get_pcm_runtime(card, "dspk-playback-l");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
if (!strcmp(rtd->codec_dai->name, "tas2552-amplifier")) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
TAS2552_PDM_CLK_IVCLKIN, clk_out_rate,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
}
}
#endif
return 0;
}
static void dai_link_setup(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
struct snd_soc_codec_conf *tegra_machine_codec_conf = NULL;
struct snd_soc_codec_conf *tegra_new_codec_conf = NULL;
struct snd_soc_dai_link *tegra_machine_dai_links = NULL;
struct snd_soc_dai_link *tegra_machine_codec_links = NULL;
const char *codec_dai_name;
int i;
/* set new codec links and conf */
tegra_machine_codec_links = tegra_machine_new_codec_links(pdev,
tegra_machine_codec_links,
&machine->num_codec_links);
if (!tegra_machine_codec_links)
goto err_alloc_dai_link;
#if 0
/* set codec init */
for (i = 0; i < machine->num_codec_links; i++) {
if (tegra_machine_codec_links[i].name) {
if (strstr(tegra_machine_codec_links[i].name,
"ti-playback-i2s1") ||
strstr(tegra_machine_codec_links[i].name,
"ti-playback-i2s2")) {
codec_dai_name =
tegra_machine_codec_links[i].codec_dai_name;
if (!strcmp("dit-hifi", codec_dai_name)) {
dev_info(&pdev->dev, "This is a dummy codec\n");
machine->is_hs_supported = false;
} else {
machine->is_hs_supported = true;
tegra_machine_codec_links[i].init =
tegra_machine_rt565x_init;
}
} else if (strstr(tegra_machine_codec_links[i].name,
"dspk-playback-r"))
tegra_machine_codec_links[i].init =
tegra_machine_dspk_init;
else if (strstr(tegra_machine_codec_links[i].name,
"dspk-playback-l"))
tegra_machine_codec_links[i].init =
tegra_machine_dspk_init;
}
}
#else
for (i = 0; i < machine->num_codec_links; i++) {
if (tegra_machine_codec_links[i].name) {
if (strstr(tegra_machine_codec_links[i].name,
"rt565x-playback") ||
strstr(tegra_machine_codec_links[i].name,
"rt565x-codec-sysclk-bclk1")) {
codec_dai_name =
tegra_machine_codec_links[i].codec_dai_name;
if (!strcmp("dit-hifi", codec_dai_name)) {
dev_info(&pdev->dev, "This is a dummy codec\n");
machine->is_hs_supported = false;
} else {
machine->is_hs_supported = true;
tegra_machine_codec_links[i].init =
tegra_machine_rt565x_init;
}
} else if (strstr(tegra_machine_codec_links[i].name,
"dspk-playback-r"))
tegra_machine_codec_links[i].init =
tegra_machine_dspk_init;
else if (strstr(tegra_machine_codec_links[i].name,
"dspk-playback-l"))
tegra_machine_codec_links[i].init =
tegra_machine_dspk_init;
}
}
#endif
tegra_new_codec_conf = tegra_machine_new_codec_conf(pdev,
tegra_new_codec_conf,
&machine->num_codec_links);
if (!tegra_new_codec_conf)
goto err_alloc_dai_link;
/* get the xbar dai link/codec conf structure */
tegra_machine_dai_links = machine->soc_data->get_dai_link();
if (!tegra_machine_dai_links)
goto err_alloc_dai_link;
tegra_machine_codec_conf = machine->soc_data->get_codec_conf();
if (!tegra_machine_codec_conf)
goto err_alloc_dai_link;
/* set ADMAIF dai_ops */
for (i = machine->soc_data->admaif_dai_link_start;
i <= machine->soc_data->admaif_dai_link_end; i++)
tegra_machine_set_dai_ops(i, &tegra_machine_pcm_ops);
/* set sfc dai_init */
tegra_machine_set_dai_init(machine->soc_data->sfc_dai_link,
&tegra_machine_sfc_init);
#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
/* set ADSP PCM/COMPR */
for (i = machine->soc_data->adsp_pcm_dai_link_start;
i <= machine->soc_data->adsp_pcm_dai_link_end; i++) {
tegra_machine_set_dai_ops(i, &tegra_machine_pcm_ops);
}
/* set ADSP COMPR */
for (i = machine->soc_data->adsp_compr_dai_link_start;
i <= machine->soc_data->adsp_compr_dai_link_end; i++) {
tegra_machine_set_dai_compr_ops(i,
&tegra_machine_compr_ops);
}
#endif
if (machine->soc_data->is_asrc_available) {
/* set ASRC params. The default is 2 channels */
for (i = 0; i < 6; i++) {
tegra_machine_set_dai_params(TEGRA186_DAI_LINK_ASRC1_TX1
+ i, (struct snd_soc_pcm_stream *)
&tegra_machine_asrc_link_params[i]);
tegra_machine_set_dai_params(TEGRA186_DAI_LINK_ASRC1_RX1
+ i, (struct snd_soc_pcm_stream *)
&tegra_machine_asrc_link_params[i]);
}
}
/* append machine specific dai_links */
card->num_links = machine->soc_data->append_dai_link(
tegra_machine_codec_links, 2 * machine->num_codec_links);
tegra_machine_dai_links = machine->soc_data->get_dai_link();
card->dai_link = tegra_machine_dai_links;
/* append machine specific codec_conf */
card->num_configs = machine->soc_data->append_codec_conf(
tegra_new_codec_conf, machine->num_codec_links);
tegra_machine_codec_conf = machine->soc_data->get_codec_conf();
card->codec_conf = tegra_machine_codec_conf;
return;
err_alloc_dai_link:
tegra_machine_remove_dai_link();
tegra_machine_remove_codec_conf();
}
static int tegra_machine_driver_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct snd_soc_card *card = &snd_soc_tegra_card;
struct tegra_machine *machine;
int ret = 0;
const struct of_device_id *match;
printk(KERN_INFO "tegra_machine_driver_probe:============probe==============="); //add 2019.8.24
card->dev = &pdev->dev;
/* parse card name first to log errors with proper device name */
ret = snd_soc_of_parse_card_name(card, "nvidia,model");
if (ret)
goto err;
match = of_match_device(tegra_machine_of_match, &pdev->dev);
if (!match) {
dev_err(&pdev->dev, "Error: No device match found\n");
return -ENODEV;
}
if (!np) {
dev_err(&pdev->dev, "No device tree node for tegra machine driver");
return -ENODEV;
}
machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_machine),
GFP_KERNEL);
if (!machine) {
ret = -ENOMEM;
dev_err(&pdev->dev, "Can't allocate struct for tegra_machine\n");
goto err;
}
machine->soc_data = (struct tegra_machine_soc_data *)match->data;
if (!machine->soc_data->get_dai_link ||
!machine->soc_data->get_bclk_ratio ||
!machine->soc_data->get_codec_conf ||
!machine->soc_data->append_dai_link ||
!machine->soc_data->append_codec_conf) {
ret = -ENODEV;
dev_err(&pdev->dev, "Error: callback APIs are missing\n");
goto err;
}
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine);
machine->is_hs_supported = false;
if (machine->soc_data->write_cdev1_state)
machine->audio_clock.clk_cdev1_state = 0;
if (machine->soc_data->write_idle_bias_off_state)
card->dapm.idle_bias_off = true;
ret = snd_soc_of_parse_audio_routing(card,
"nvidia,audio-routing");
if (ret)
goto err;
if (machine->soc_data->is_clk_rate_via_dt) {
if (of_property_read_u32(np, "nvidia,num-clk",
&machine->audio_clock.num_clk) < 0) {
dev_err(&pdev->dev,
"Missing property nvidia,num-clk\n");
ret = -ENODEV;
goto err;
}
if (of_property_read_u32_array(np, "nvidia,clk-rates",
(u32 *)&machine->audio_clock.clk_rates,
machine->audio_clock.num_clk) < 0) {
dev_err(&pdev->dev,
"Missing property nvidia,clk-rates\n");
ret = -ENODEV;
goto err;
}
}
tegra_machine_dma_set_mask(pdev);
dai_link_setup(pdev);
ret = tegra_alt_asoc_utils_init(&machine->audio_clock,
&pdev->dev,
card);
if (ret)
goto err_alloc_dai_link;
ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed--- (%d)\n",
ret);
goto err_alloc_dai_link;
}
#ifdef CONFIG_ANDROID
ignore_suspend(card);
#endif
tegra_machine_add_i2s_codec_controls(card,
machine->soc_data->num_xbar_dai_links +
machine->num_codec_links);
return 0;
err_alloc_dai_link:
tegra_machine_remove_dai_link();
tegra_machine_remove_codec_conf();
err:
return ret;
}
Kconfig
config SND_SOC_TEGRA_T186REF_MOBILE_ALT
tristate "SoC Audio support for T186Ref Mobile"
depends on SND_SOC_TEGRA_T186REF_ALT
select SND_SOC_RT5659
select SND_SOC_TLV320AIC32X4
select SND_SOC_TLV320AIC32X4_I2C
help
Say Y or M here.
tegra_defconfig
#CONFIG_SND_SOC_TLV320AIC32X4=y
#CONFIG_SND_SOC_TLV320AIC32X4_I2C=y
The following are the specific steps:
- Install JetPack4.2 using SDK manager
- Compile kernel source code
export CROSS_COMPILE=/home/work/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
export TEGRA_KERNEL_OUT=/home/work/kernel-out
export ARCH=arm64
make O=$TEGRA_KERNEL_OUT tegra_defconfig
make O=$TEGRA_KERNEL_OUT zImage -j4
make O=$TEGRA_KERNEL_OUT dtbs -j4
- Copy image to the Linux_for_Tegra/kernel folder
- Copy DTB file from arch/arm64/boot/dts to Linux_for_Tegra/kernel/dtb folder
- Refresh the system with the command "sudo./ flash.sh jetson-tx2 mmcblk0p1"
The files in the Linux_for_Tegra folder have not been modified except for DTB and image.
Thanks