Lines Matching +full:ac97 +full:- +full:controller

1 // SPDX-License-Identifier: GPL-2.0-only
5 * (c) 2007-2009 MSC Vertriebsges.m.b.H.,
8 * Au1xxx-PSC AC97 glue.
22 #include <asm/mach-au1x00/au1000.h>
23 #include <asm/mach-au1x00/au1xxx_psc.h>
54 /* this could theoretically work, but ac97->bus->card->private_data can be NULL
60 struct snd_soc_card *c = x->bus->card->private_data;
61 return snd_soc_dai_get_drvdata(c->snd_soc_rtd_to_cpu(rtd, 0));
70 /* AC97 controller reads codec register */
71 static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, in au1xpsc_ac97_read() argument
74 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); in au1xpsc_ac97_read()
83 mutex_lock(&pscdata->lock); in au1xpsc_ac97_read()
94 } while (--tmo); in au1xpsc_ac97_read()
101 mutex_unlock(&pscdata->lock); in au1xpsc_ac97_read()
106 } while (--retry && !tmo); in au1xpsc_ac97_read()
111 /* AC97 controller writes to codec register */
112 static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, in au1xpsc_ac97_write() argument
115 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); in au1xpsc_ac97_write()
123 mutex_lock(&pscdata->lock); in au1xpsc_ac97_write()
134 } while (--tmo); in au1xpsc_ac97_write()
139 mutex_unlock(&pscdata->lock); in au1xpsc_ac97_write()
140 } while (--retry && !tmo); in au1xpsc_ac97_write()
143 /* AC97 controller asserts a warm reset */
144 static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97) in au1xpsc_ac97_warm_reset() argument
146 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); in au1xpsc_ac97_warm_reset()
155 static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) in au1xpsc_ac97_cold_reset() argument
157 struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); in au1xpsc_ac97_cold_reset()
179 while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) in au1xpsc_ac97_cold_reset()
183 printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n"); in au1xpsc_ac97_cold_reset()
187 /* enable the ac97 function */ in au1xpsc_ac97_cold_reset()
188 __raw_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); in au1xpsc_ac97_cold_reset()
191 /* wait for AC97 core to become ready */ in au1xpsc_ac97_cold_reset()
193 while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) in au1xpsc_ac97_cold_reset()
196 printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n"); in au1xpsc_ac97_cold_reset()
199 /* AC97 controller operations */
213 int chans, t, stype = substream->stream; in au1xpsc_ac97_hw_params()
223 if ((PSC_AC97CFG_GET_LEN(r) != params->msbits) || in au1xpsc_ac97_hw_params()
224 (pscdata->rate != params_rate(params))) in au1xpsc_ac97_hw_params()
225 return -EINVAL; in au1xpsc_ac97_hw_params()
228 /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */ in au1xpsc_ac97_hw_params()
230 r |= PSC_AC97CFG_SET_LEN(params->msbits); in au1xpsc_ac97_hw_params()
247 /* ac97 engine is about to be disabled */ in au1xpsc_ac97_hw_params()
248 mutex_lock(&pscdata->lock); in au1xpsc_ac97_hw_params()
250 /* disable AC97 device controller first... */ in au1xpsc_ac97_hw_params()
256 while ((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t) in au1xpsc_ac97_hw_params()
260 printk(KERN_ERR "PSC-AC97: can't disable!\n"); in au1xpsc_ac97_hw_params()
266 /* ...enable the AC97 controller again... */ in au1xpsc_ac97_hw_params()
272 while ((!(__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t) in au1xpsc_ac97_hw_params()
276 printk(KERN_ERR "PSC-AC97: can't enable!\n"); in au1xpsc_ac97_hw_params()
278 mutex_unlock(&pscdata->lock); in au1xpsc_ac97_hw_params()
280 pscdata->cfg = r; in au1xpsc_ac97_hw_params()
281 pscdata->rate = params_rate(params); in au1xpsc_ac97_hw_params()
292 int ret, stype = substream->stream; in au1xpsc_ac97_trigger()
317 ret = -EINVAL; in au1xpsc_ac97_trigger()
326 snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]); in au1xpsc_ac97_startup()
332 return au1xpsc_ac97_workdata ? 0 : -ENODEV; in au1xpsc_ac97_probe()
359 .name = "au1xpsc-ac97",
370 wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data), in au1xpsc_ac97_drvprobe()
373 return -ENOMEM; in au1xpsc_ac97_drvprobe()
375 mutex_init(&wd->lock); in au1xpsc_ac97_drvprobe()
377 wd->mmio = devm_platform_ioremap_resource(pdev, 0); in au1xpsc_ac97_drvprobe()
378 if (IS_ERR(wd->mmio)) in au1xpsc_ac97_drvprobe()
379 return PTR_ERR(wd->mmio); in au1xpsc_ac97_drvprobe()
383 return -EBUSY; in au1xpsc_ac97_drvprobe()
384 wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; in au1xpsc_ac97_drvprobe()
388 return -EBUSY; in au1xpsc_ac97_drvprobe()
389 wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; in au1xpsc_ac97_drvprobe()
391 /* configuration: max dma trigger threshold, enable ac97 */ in au1xpsc_ac97_drvprobe()
392 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | in au1xpsc_ac97_drvprobe()
404 /* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */ in au1xpsc_ac97_drvprobe()
405 memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template, in au1xpsc_ac97_drvprobe()
407 wd->dai_drv.name = dev_name(&pdev->dev); in au1xpsc_ac97_drvprobe()
415 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component, in au1xpsc_ac97_drvprobe()
416 &wd->dai_drv, 1); in au1xpsc_ac97_drvprobe()
428 snd_soc_unregister_component(&pdev->dev); in au1xpsc_ac97_drvremove()
445 wd->pm[0] = __raw_readl(PSC_SEL(wd)); in au1xpsc_ac97_drvsuspend()
460 __raw_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd)); in au1xpsc_ac97_drvresume()
463 /* after this point the ac97 core will cold-reset the codec. in au1xpsc_ac97_drvresume()
464 * During cold-reset the PSC is reinitialized and the last in au1xpsc_ac97_drvresume()
495 MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");