if (atomic_inc_return(&priv->n_active_ch) == 1) {
ret = pm_runtime_resume_and_get(dev); if (ret < 0) goto error_ret;
/* select clock source, e.g. 0 for "dfsdm" or 1 for "audio" */
clk_src = priv->aclk ? 1 : 0;
ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
DFSDM_CHCFGR1_CKOUTSRC_MASK,
DFSDM_CHCFGR1_CKOUTSRC(clk_src)); if (ret < 0) goto pm_put;
/* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */
ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
DFSDM_CHCFGR1_CKOUTDIV_MASK,
DFSDM_CHCFGR1_CKOUTDIV(clk_div)); if (ret < 0) goto pm_put;
/* Global enable of DFSDM interface */
ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
DFSDM_CHCFGR1_DFSDMEN_MASK,
DFSDM_CHCFGR1_DFSDMEN(1)); if (ret < 0) goto pm_put;
}
/** *stm32_dfsdm_stop_dfsdm-stopglobalDFSDMinterface. * *Disableinterfaceifn_active_chisnull *@dfsdm:Handleusedtoretrievedfsdmcontext.
*/ int stm32_dfsdm_stop_dfsdm(struct stm32_dfsdm *dfsdm)
{ struct dfsdm_priv *priv = to_stm32_dfsdm_priv(dfsdm); int ret;
if (atomic_dec_and_test(&priv->n_active_ch)) { /* Global disable of DFSDM interface */
ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
DFSDM_CHCFGR1_DFSDMEN_MASK,
DFSDM_CHCFGR1_DFSDMEN(0)); if (ret < 0) return ret;
/* Stop SPI CLKOUT */
ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
DFSDM_CHCFGR1_CKOUTDIV_MASK,
DFSDM_CHCFGR1_CKOUTDIV(0)); if (ret < 0) return ret;
priv->dfsdm.base = devm_platform_get_and_ioremap_resource(pdev, 0,
&res); if (IS_ERR(priv->dfsdm.base)) return PTR_ERR(priv->dfsdm.base);
priv->dfsdm.phys_base = res->start;
/* *"dfsdm"clockismandatoryforDFSDMperipheralclocking. *"dfsdm"or"audio"clockscanbeusedassourceclockfor *theSPIclockoutsignalandinternalprocessing,depending *onusecase.
*/
priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); if (IS_ERR(priv->clk)) return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), "Failed to get clock\n");
priv->aclk = devm_clk_get(&pdev->dev, "audio"); if (IS_ERR(priv->aclk))
priv->aclk = NULL;
if (priv->aclk)
clk_freq = clk_get_rate(priv->aclk); else
clk_freq = clk_get_rate(priv->clk);
/* SPI clock out frequency */
ret = of_property_read_u32(pdev->dev.of_node, "spi-max-frequency",
&spi_freq); if (ret < 0) { /* No SPI master mode */ return0;
}
divider = div_u64_rem(clk_freq, spi_freq, &rem); /* Round up divider when ckout isn't precise, not to exceed spi_freq */ if (rem)
divider++;
/* programmable divider is in range of [2:256] */ if (divider < 2 || divider > 256) {
dev_err(&pdev->dev, "spi-max-frequency not achievable\n"); return -EINVAL;
}
ret = regmap_read(dfsdm->regmap, DFSDM_IPIDR, &id); if (ret) return ret;
if (id != dev_data->ipid) {
dev_err(&pdev->dev, "Unexpected IP version: 0x%x", id); return -EINVAL;
}
for_each_child_of_node(np, child) {
ret = of_property_read_string(child, "compatible", &compat); if (ret) continue; /* Count only child nodes with dfsdm compatible */ if (strstr(compat, "dfsdm"))
count++;
}
ret = regmap_read(dfsdm->regmap, DFSDM_HWCFGR, &val); if (ret) return ret;
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.