/* instance data. There can be only one, MacLeod!!!! */ staticstruct au1xpsc_audio_data *au1xpsc_ac97_workdata;
#if 0
/* this could theoretically work, but ac97->bus->card->private_data can be NULL * when snd_ac97_mixer() is called; I don't know if the rest further down the * chain are always valid either.
*/ staticinlinestruct au1xpsc_audio_data *ac97_to_pscdata(struct snd_ac97 *x)
{ struct snd_soc_card *c = x->bus->card->private_data; return snd_soc_dai_get_drvdata(c->snd_soc_rtd_to_cpu(rtd, 0));
}
/* wait for PSC to indicate it's ready */
i = 1000; while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i))
msleep(1);
if (i == 0) {
printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n"); return;
}
/* enable the ac97 function */
__raw_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
wmb(); /* drain writebuffer */
/* wait for AC97 core to become ready */
i = 1000; while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i))
msleep(1); if (i == 0)
printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n");
}
r = ro = __raw_readl(AC97_CFG(pscdata));
stat = __raw_readl(AC97_STAT(pscdata));
/* already active? */ if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) { /* reject parameters not currently set up */ if ((PSC_AC97CFG_GET_LEN(r) != params->msbits) ||
(pscdata->rate != params_rate(params))) return -EINVAL;
} else {
/* set sample bitdepth: REG[24:21]=(BITS-2)/2 */
r &= ~PSC_AC97CFG_LEN_MASK;
r |= PSC_AC97CFG_SET_LEN(params->msbits);
/* channels: enable slots for front L/R channel */ if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
r &= ~PSC_AC97CFG_TXSLOT_MASK;
r |= PSC_AC97CFG_TXSLOT_ENA(3);
r |= PSC_AC97CFG_TXSLOT_ENA(4);
} else {
r &= ~PSC_AC97CFG_RXSLOT_MASK;
r |= PSC_AC97CFG_RXSLOT_ENA(3);
r |= PSC_AC97CFG_RXSLOT_ENA(4);
}
/* do we need to poke the hardware? */ if (!(r ^ ro)) goto out;
/* ac97 engine is about to be disabled */
mutex_lock(&pscdata->lock);
/* preserve PSC clock source set up by platform */
sel = __raw_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
__raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
wmb(); /* drain writebuffer */
__raw_writel(0, PSC_SEL(wd));
wmb(); /* drain writebuffer */
__raw_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
wmb(); /* drain writebuffer */
/* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */
memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template, sizeof(struct snd_soc_dai_driver));
wd->dai_drv.name = dev_name(&pdev->dev);
platform_set_drvdata(pdev, wd);
ret = snd_soc_set_ac97_ops(&psc_ac97_ops); if (ret) return ret;
ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
&wd->dai_drv, 1); if (ret) return ret;
/* after this point the ac97 core will cold-reset the codec. * During cold-reset the PSC is reinitialized and the last * configuration set up in hw_params() is restored.
*/ return 0;
}
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.