// SPDX-License-Identifier: GPL-2.0-or-later // // This driver supports the DMIC in Allwinner's H6 SoCs. // // Copyright 2021 Ban Tao <fengzheng923@gmail.com>
/* DMIC num is N+1 */
regmap_update_bits(host->regmap, SUN50I_DMIC_CH_NUM,
SUN50I_DMIC_CH_NUM_N_MASK,
SUN50I_DMIC_CH_NUM_N(channels - 1));
regmap_write(host->regmap, SUN50I_DMIC_HPF_CTRL, chan_en);
regmap_update_bits(host->regmap, SUN50I_DMIC_EN_CTL,
SUN50I_DMIC_EN_CTL_CHAN_MASK,
SUN50I_DMIC_EN_CTL_CHAN(chan_en));
switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE:
regmap_update_bits(host->regmap, SUN50I_DMIC_RXFIFO_CTL,
SUN50I_DMIC_RXFIFO_CTL_SAMPLE_MASK,
SUN50I_DMIC_RXFIFO_CTL_SAMPLE_16); break; case SNDRV_PCM_FORMAT_S24_LE:
regmap_update_bits(host->regmap, SUN50I_DMIC_RXFIFO_CTL,
SUN50I_DMIC_RXFIFO_CTL_SAMPLE_MASK,
SUN50I_DMIC_RXFIFO_CTL_SAMPLE_24); break; default:
dev_err(cpu_dai->dev, "Invalid format!\n"); return -EINVAL;
} /* The hardware supports FIFO mode 1 for 24-bit samples */
regmap_update_bits(host->regmap, SUN50I_DMIC_RXFIFO_CTL,
SUN50I_DMIC_RXFIFO_CTL_MODE_MASK,
SUN50I_DMIC_RXFIFO_CTL_MODE_MSB);
switch (rate) { case 11025: case 22050: case 44100:
mclk = 22579200; break; case 8000: case 12000: case 16000: case 24000: case 32000: case 48000:
mclk = 24576000; break; default:
dev_err(cpu_dai->dev, "Invalid rate!\n"); return -EINVAL;
}
if (clk_set_rate(host->dmic_clk, mclk)) {
dev_err(cpu_dai->dev, "mclk : %u not support\n", mclk); return -EINVAL;
}
for (i = 0; i < ARRAY_SIZE(dmic_rate_s); i++) { if (dmic_rate_s[i].samplerate == rate) {
regmap_update_bits(host->regmap, SUN50I_DMIC_SR,
SUN50I_DMIC_SR_SAMPLE_RATE_MASK,
SUN50I_DMIC_SR_SAMPLE_RATE(dmic_rate_s[i].rate_bit)); break;
}
}
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); if (!host) return -ENOMEM;
/* Get the addresses */
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(base)) return dev_err_probe(&pdev->dev, PTR_ERR(base), "get resource failed.\n");
/* Clocks */
host->bus_clk = devm_clk_get(&pdev->dev, "bus"); if (IS_ERR(host->bus_clk)) return dev_err_probe(&pdev->dev, PTR_ERR(host->bus_clk), "failed to get bus clock.\n");
host->dmic_clk = devm_clk_get(&pdev->dev, "mod"); if (IS_ERR(host->dmic_clk)) return dev_err_probe(&pdev->dev, PTR_ERR(host->dmic_clk), "failed to get dmic clock.\n");
host->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); if (IS_ERR(host->rst)) return dev_err_probe(&pdev->dev, PTR_ERR(host->rst), "Failed to get reset.\n");
reset_control_deassert(host->rst);
ret = devm_snd_soc_register_component(&pdev->dev, &sun50i_dmic_component,
&sun50i_dmic_dai, 1); if (ret) return dev_err_probe(&pdev->dev, ret, "failed to register component.\n");
pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) {
ret = sun50i_dmic_runtime_resume(&pdev->dev); if (ret) goto err_disable_runtime_pm;
}
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); if (ret) goto err_suspend;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.