ret = regcache_sync(spdif->regmap); if (ret) {
clk_disable_unprepare(spdif->mclk);
clk_disable_unprepare(spdif->hclk);
}
return ret;
}
staticint rk_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{ struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); unsignedint val = SPDIF_CFGR_HALFWORD_ENABLE; int srate, mclk; int ret;
srate = params_rate(params);
mclk = srate * 128;
switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE:
val |= SPDIF_CFGR_VDW_16; break; case SNDRV_PCM_FORMAT_S20_3LE:
val |= SPDIF_CFGR_VDW_20; break; case SNDRV_PCM_FORMAT_S24_LE:
val |= SPDIF_CFGR_VDW_24; break; default: return -EINVAL;
}
/* Set clock and calculate divider */
ret = clk_set_rate(spdif->mclk, mclk); if (ret != 0) {
dev_err(spdif->dev, "Failed to set module clock rate: %d\n",
ret); return ret;
}
ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
SPDIF_CFGR_CLK_DIV_MASK |
SPDIF_CFGR_HALFWORD_ENABLE |
SDPIF_CFGR_VDW_MASK, val);
return ret;
}
staticint rk_spdif_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
{ struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); int ret;
switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
SPDIF_DMACR_TDE_ENABLE |
SPDIF_DMACR_TDL_MASK,
SPDIF_DMACR_TDE_ENABLE |
SPDIF_DMACR_TDL(16));
if (ret != 0) return ret;
ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
SPDIF_XFER_TXS_START,
SPDIF_XFER_TXS_START); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
SPDIF_DMACR_TDE_ENABLE,
SPDIF_DMACR_TDE_DISABLE);
if (ret != 0) return ret;
ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
SPDIF_XFER_TXS_START,
SPDIF_XFER_TXS_STOP); break; default:
ret = -EINVAL; break;
}
staticbool rk_spdif_wr_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case SPDIF_CFGR: case SPDIF_DMACR: case SPDIF_INTCR: case SPDIF_XFER: case SPDIF_SMPDR: returntrue; default: returnfalse;
}
}
staticbool rk_spdif_rd_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case SPDIF_CFGR: case SPDIF_SDBLR: case SPDIF_INTCR: case SPDIF_INTSR: case SPDIF_XFER: case SPDIF_SMPDR: returntrue; default: returnfalse;
}
}
staticbool rk_spdif_volatile_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case SPDIF_INTSR: case SPDIF_SDBLR: case SPDIF_SMPDR: returntrue; default: returnfalse;
}
}
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.