Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Au12x0/Au1550 PSC ALSA ASoC audio support.
0004  *
0005  * (c) 2007-2009 MSC Vertriebsges.m.b.H.,
0006  *  Manuel Lauss <manuel.lauss@gmail.com>
0007  *
0008  * Au1xxx-PSC AC97 glue.
0009  */
0010 
0011 #include <linux/init.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/device.h>
0015 #include <linux/delay.h>
0016 #include <linux/mutex.h>
0017 #include <linux/suspend.h>
0018 #include <sound/core.h>
0019 #include <sound/pcm.h>
0020 #include <sound/initval.h>
0021 #include <sound/soc.h>
0022 #include <asm/mach-au1x00/au1000.h>
0023 #include <asm/mach-au1x00/au1xxx_psc.h>
0024 
0025 #include "psc.h"
0026 
0027 /* how often to retry failed codec register reads/writes */
0028 #define AC97_RW_RETRIES 5
0029 
0030 #define AC97_DIR    \
0031     (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
0032 
0033 #define AC97_RATES  \
0034     SNDRV_PCM_RATE_8000_48000
0035 
0036 #define AC97_FMTS   \
0037     (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE)
0038 
0039 #define AC97PCR_START(stype)    \
0040     ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TS : PSC_AC97PCR_RS)
0041 #define AC97PCR_STOP(stype) \
0042     ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TP : PSC_AC97PCR_RP)
0043 #define AC97PCR_CLRFIFO(stype)  \
0044     ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
0045 
0046 #define AC97STAT_BUSY(stype)    \
0047     ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
0048 
0049 /* instance data. There can be only one, MacLeod!!!! */
0050 static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
0051 
0052 #if 0
0053 
0054 /* this could theoretically work, but ac97->bus->card->private_data can be NULL
0055  * when snd_ac97_mixer() is called; I don't know if the rest further down the
0056  * chain are always valid either.
0057  */
0058 static inline struct au1xpsc_audio_data *ac97_to_pscdata(struct snd_ac97 *x)
0059 {
0060     struct snd_soc_card *c = x->bus->card->private_data;
0061     return snd_soc_dai_get_drvdata(c->asoc_rtd_to_cpu(rtd, 0));
0062 }
0063 
0064 #else
0065 
0066 #define ac97_to_pscdata(x)  au1xpsc_ac97_workdata
0067 
0068 #endif
0069 
0070 /* AC97 controller reads codec register */
0071 static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
0072                     unsigned short reg)
0073 {
0074     struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
0075     unsigned short retry, tmo;
0076     unsigned long data;
0077 
0078     __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
0079     wmb(); /* drain writebuffer */
0080 
0081     retry = AC97_RW_RETRIES;
0082     do {
0083         mutex_lock(&pscdata->lock);
0084 
0085         __raw_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg),
0086               AC97_CDC(pscdata));
0087         wmb(); /* drain writebuffer */
0088 
0089         tmo = 20;
0090         do {
0091             udelay(21);
0092             if (__raw_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
0093                 break;
0094         } while (--tmo);
0095 
0096         data = __raw_readl(AC97_CDC(pscdata));
0097 
0098         __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
0099         wmb(); /* drain writebuffer */
0100 
0101         mutex_unlock(&pscdata->lock);
0102 
0103         if (reg != ((data >> 16) & 0x7f))
0104             tmo = 1;    /* wrong register, try again */
0105 
0106     } while (--retry && !tmo);
0107 
0108     return retry ? data & 0xffff : 0xffff;
0109 }
0110 
0111 /* AC97 controller writes to codec register */
0112 static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
0113                 unsigned short val)
0114 {
0115     struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
0116     unsigned int tmo, retry;
0117 
0118     __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
0119     wmb(); /* drain writebuffer */
0120 
0121     retry = AC97_RW_RETRIES;
0122     do {
0123         mutex_lock(&pscdata->lock);
0124 
0125         __raw_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff),
0126               AC97_CDC(pscdata));
0127         wmb(); /* drain writebuffer */
0128 
0129         tmo = 20;
0130         do {
0131             udelay(21);
0132             if (__raw_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
0133                 break;
0134         } while (--tmo);
0135 
0136         __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
0137         wmb(); /* drain writebuffer */
0138 
0139         mutex_unlock(&pscdata->lock);
0140     } while (--retry && !tmo);
0141 }
0142 
0143 /* AC97 controller asserts a warm reset */
0144 static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97)
0145 {
0146     struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
0147 
0148     __raw_writel(PSC_AC97RST_SNC, AC97_RST(pscdata));
0149     wmb(); /* drain writebuffer */
0150     msleep(10);
0151     __raw_writel(0, AC97_RST(pscdata));
0152     wmb(); /* drain writebuffer */
0153 }
0154 
0155 static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
0156 {
0157     struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97);
0158     int i;
0159 
0160     /* disable PSC during cold reset */
0161     __raw_writel(0, AC97_CFG(au1xpsc_ac97_workdata));
0162     wmb(); /* drain writebuffer */
0163     __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata));
0164     wmb(); /* drain writebuffer */
0165 
0166     /* issue cold reset */
0167     __raw_writel(PSC_AC97RST_RST, AC97_RST(pscdata));
0168     wmb(); /* drain writebuffer */
0169     msleep(500);
0170     __raw_writel(0, AC97_RST(pscdata));
0171     wmb(); /* drain writebuffer */
0172 
0173     /* enable PSC */
0174     __raw_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata));
0175     wmb(); /* drain writebuffer */
0176 
0177     /* wait for PSC to indicate it's ready */
0178     i = 1000;
0179     while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i))
0180         msleep(1);
0181 
0182     if (i == 0) {
0183         printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n");
0184         return;
0185     }
0186 
0187     /* enable the ac97 function */
0188     __raw_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
0189     wmb(); /* drain writebuffer */
0190 
0191     /* wait for AC97 core to become ready */
0192     i = 1000;
0193     while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i))
0194         msleep(1);
0195     if (i == 0)
0196         printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n");
0197 }
0198 
0199 /* AC97 controller operations */
0200 static struct snd_ac97_bus_ops psc_ac97_ops = {
0201     .read       = au1xpsc_ac97_read,
0202     .write      = au1xpsc_ac97_write,
0203     .reset      = au1xpsc_ac97_cold_reset,
0204     .warm_reset = au1xpsc_ac97_warm_reset,
0205 };
0206 
0207 static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
0208                   struct snd_pcm_hw_params *params,
0209                   struct snd_soc_dai *dai)
0210 {
0211     struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
0212     unsigned long r, ro, stat;
0213     int chans, t, stype = substream->stream;
0214 
0215     chans = params_channels(params);
0216 
0217     r = ro = __raw_readl(AC97_CFG(pscdata));
0218     stat = __raw_readl(AC97_STAT(pscdata));
0219 
0220     /* already active? */
0221     if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) {
0222         /* reject parameters not currently set up */
0223         if ((PSC_AC97CFG_GET_LEN(r) != params->msbits) ||
0224             (pscdata->rate != params_rate(params)))
0225             return -EINVAL;
0226     } else {
0227 
0228         /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */
0229         r &= ~PSC_AC97CFG_LEN_MASK;
0230         r |= PSC_AC97CFG_SET_LEN(params->msbits);
0231 
0232         /* channels: enable slots for front L/R channel */
0233         if (stype == SNDRV_PCM_STREAM_PLAYBACK) {
0234             r &= ~PSC_AC97CFG_TXSLOT_MASK;
0235             r |= PSC_AC97CFG_TXSLOT_ENA(3);
0236             r |= PSC_AC97CFG_TXSLOT_ENA(4);
0237         } else {
0238             r &= ~PSC_AC97CFG_RXSLOT_MASK;
0239             r |= PSC_AC97CFG_RXSLOT_ENA(3);
0240             r |= PSC_AC97CFG_RXSLOT_ENA(4);
0241         }
0242 
0243         /* do we need to poke the hardware? */
0244         if (!(r ^ ro))
0245             goto out;
0246 
0247         /* ac97 engine is about to be disabled */
0248         mutex_lock(&pscdata->lock);
0249 
0250         /* disable AC97 device controller first... */
0251         __raw_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
0252         wmb(); /* drain writebuffer */
0253 
0254         /* ...wait for it... */
0255         t = 100;
0256         while ((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t)
0257             msleep(1);
0258 
0259         if (!t)
0260             printk(KERN_ERR "PSC-AC97: can't disable!\n");
0261 
0262         /* ...write config... */
0263         __raw_writel(r, AC97_CFG(pscdata));
0264         wmb(); /* drain writebuffer */
0265 
0266         /* ...enable the AC97 controller again... */
0267         __raw_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
0268         wmb(); /* drain writebuffer */
0269 
0270         /* ...and wait for ready bit */
0271         t = 100;
0272         while ((!(__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t)
0273             msleep(1);
0274 
0275         if (!t)
0276             printk(KERN_ERR "PSC-AC97: can't enable!\n");
0277 
0278         mutex_unlock(&pscdata->lock);
0279 
0280         pscdata->cfg = r;
0281         pscdata->rate = params_rate(params);
0282     }
0283 
0284 out:
0285     return 0;
0286 }
0287 
0288 static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
0289                 int cmd, struct snd_soc_dai *dai)
0290 {
0291     struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
0292     int ret, stype = substream->stream;
0293 
0294     ret = 0;
0295 
0296     switch (cmd) {
0297     case SNDRV_PCM_TRIGGER_START:
0298     case SNDRV_PCM_TRIGGER_RESUME:
0299         __raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
0300         wmb(); /* drain writebuffer */
0301         __raw_writel(AC97PCR_START(stype), AC97_PCR(pscdata));
0302         wmb(); /* drain writebuffer */
0303         break;
0304     case SNDRV_PCM_TRIGGER_STOP:
0305     case SNDRV_PCM_TRIGGER_SUSPEND:
0306         __raw_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata));
0307         wmb(); /* drain writebuffer */
0308 
0309         while (__raw_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype))
0310             asm volatile ("nop");
0311 
0312         __raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
0313         wmb(); /* drain writebuffer */
0314 
0315         break;
0316     default:
0317         ret = -EINVAL;
0318     }
0319     return ret;
0320 }
0321 
0322 static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream,
0323                 struct snd_soc_dai *dai)
0324 {
0325     struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
0326     snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]);
0327     return 0;
0328 }
0329 
0330 static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
0331 {
0332     return au1xpsc_ac97_workdata ? 0 : -ENODEV;
0333 }
0334 
0335 static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
0336     .startup    = au1xpsc_ac97_startup,
0337     .trigger    = au1xpsc_ac97_trigger,
0338     .hw_params  = au1xpsc_ac97_hw_params,
0339 };
0340 
0341 static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
0342     .probe          = au1xpsc_ac97_probe,
0343     .playback = {
0344         .rates      = AC97_RATES,
0345         .formats    = AC97_FMTS,
0346         .channels_min   = 2,
0347         .channels_max   = 2,
0348     },
0349     .capture = {
0350         .rates      = AC97_RATES,
0351         .formats    = AC97_FMTS,
0352         .channels_min   = 2,
0353         .channels_max   = 2,
0354     },
0355     .ops = &au1xpsc_ac97_dai_ops,
0356 };
0357 
0358 static const struct snd_soc_component_driver au1xpsc_ac97_component = {
0359     .name           = "au1xpsc-ac97",
0360     .legacy_dai_naming  = 1,
0361 };
0362 
0363 static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
0364 {
0365     int ret;
0366     struct resource *dmares;
0367     unsigned long sel;
0368     struct au1xpsc_audio_data *wd;
0369 
0370     wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data),
0371               GFP_KERNEL);
0372     if (!wd)
0373         return -ENOMEM;
0374 
0375     mutex_init(&wd->lock);
0376 
0377     wd->mmio = devm_platform_ioremap_resource(pdev, 0);
0378     if (IS_ERR(wd->mmio))
0379         return PTR_ERR(wd->mmio);
0380 
0381     dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
0382     if (!dmares)
0383         return -EBUSY;
0384     wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
0385 
0386     dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
0387     if (!dmares)
0388         return -EBUSY;
0389     wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
0390 
0391     /* configuration: max dma trigger threshold, enable ac97 */
0392     wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
0393           PSC_AC97CFG_DE_ENABLE;
0394 
0395     /* preserve PSC clock source set up by platform  */
0396     sel = __raw_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
0397     __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
0398     wmb(); /* drain writebuffer */
0399     __raw_writel(0, PSC_SEL(wd));
0400     wmb(); /* drain writebuffer */
0401     __raw_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
0402     wmb(); /* drain writebuffer */
0403 
0404     /* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */
0405     memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template,
0406            sizeof(struct snd_soc_dai_driver));
0407     wd->dai_drv.name = dev_name(&pdev->dev);
0408 
0409     platform_set_drvdata(pdev, wd);
0410 
0411     ret = snd_soc_set_ac97_ops(&psc_ac97_ops);
0412     if (ret)
0413         return ret;
0414 
0415     ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
0416                      &wd->dai_drv, 1);
0417     if (ret)
0418         return ret;
0419 
0420     au1xpsc_ac97_workdata = wd;
0421     return 0;
0422 }
0423 
0424 static int au1xpsc_ac97_drvremove(struct platform_device *pdev)
0425 {
0426     struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
0427 
0428     snd_soc_unregister_component(&pdev->dev);
0429 
0430     /* disable PSC completely */
0431     __raw_writel(0, AC97_CFG(wd));
0432     wmb(); /* drain writebuffer */
0433     __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
0434     wmb(); /* drain writebuffer */
0435 
0436     au1xpsc_ac97_workdata = NULL;   /* MDEV */
0437 
0438     return 0;
0439 }
0440 
0441 #ifdef CONFIG_PM
0442 static int au1xpsc_ac97_drvsuspend(struct device *dev)
0443 {
0444     struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
0445 
0446     /* save interesting registers and disable PSC */
0447     wd->pm[0] = __raw_readl(PSC_SEL(wd));
0448 
0449     __raw_writel(0, AC97_CFG(wd));
0450     wmb(); /* drain writebuffer */
0451     __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
0452     wmb(); /* drain writebuffer */
0453 
0454     return 0;
0455 }
0456 
0457 static int au1xpsc_ac97_drvresume(struct device *dev)
0458 {
0459     struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
0460 
0461     /* restore PSC clock config */
0462     __raw_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd));
0463     wmb(); /* drain writebuffer */
0464 
0465     /* after this point the ac97 core will cold-reset the codec.
0466      * During cold-reset the PSC is reinitialized and the last
0467      * configuration set up in hw_params() is restored.
0468      */
0469     return 0;
0470 }
0471 
0472 static const struct dev_pm_ops au1xpscac97_pmops = {
0473     .suspend    = au1xpsc_ac97_drvsuspend,
0474     .resume     = au1xpsc_ac97_drvresume,
0475 };
0476 
0477 #define AU1XPSCAC97_PMOPS &au1xpscac97_pmops
0478 
0479 #else
0480 
0481 #define AU1XPSCAC97_PMOPS NULL
0482 
0483 #endif
0484 
0485 static struct platform_driver au1xpsc_ac97_driver = {
0486     .driver = {
0487         .name   = "au1xpsc_ac97",
0488         .pm = AU1XPSCAC97_PMOPS,
0489     },
0490     .probe      = au1xpsc_ac97_drvprobe,
0491     .remove     = au1xpsc_ac97_drvremove,
0492 };
0493 
0494 module_platform_driver(au1xpsc_ac97_driver);
0495 
0496 MODULE_LICENSE("GPL");
0497 MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
0498 MODULE_AUTHOR("Manuel Lauss");
0499