root/sound/soc/au1x/ac97c.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. RD
  2. WR
  3. au1xac97c_ac97_read
  4. au1xac97c_ac97_write
  5. au1xac97c_ac97_warm_reset
  6. au1xac97c_ac97_cold_reset
  7. alchemy_ac97c_startup
  8. au1xac97c_dai_probe
  9. au1xac97c_drvprobe
  10. au1xac97c_drvremove
  11. au1xac97c_drvsuspend
  12. au1xac97c_drvresume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Au1000/Au1500/Au1100 AC97C controller driver for ASoC
   4  *
   5  * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
   6  *
   7  * based on the old ALSA driver originally written by
   8  *                      Charles Eidsness <charles@cooper-street.com>
   9  */
  10 
  11 #include <linux/init.h>
  12 #include <linux/module.h>
  13 #include <linux/slab.h>
  14 #include <linux/device.h>
  15 #include <linux/delay.h>
  16 #include <linux/mutex.h>
  17 #include <linux/platform_device.h>
  18 #include <linux/suspend.h>
  19 #include <sound/core.h>
  20 #include <sound/pcm.h>
  21 #include <sound/initval.h>
  22 #include <sound/soc.h>
  23 #include <asm/mach-au1x00/au1000.h>
  24 
  25 #include "psc.h"
  26 
  27 /* register offsets and bits */
  28 #define AC97_CONFIG     0x00
  29 #define AC97_STATUS     0x04
  30 #define AC97_DATA       0x08
  31 #define AC97_CMDRESP    0x0c
  32 #define AC97_ENABLE     0x10
  33 
  34 #define CFG_RC(x)       (((x) & 0x3ff) << 13)   /* valid rx slots mask */
  35 #define CFG_XS(x)       (((x) & 0x3ff) << 3)    /* valid tx slots mask */
  36 #define CFG_SG          (1 << 2)        /* sync gate */
  37 #define CFG_SN          (1 << 1)        /* sync control */
  38 #define CFG_RS          (1 << 0)        /* acrst# control */
  39 #define STAT_XU         (1 << 11)       /* tx underflow */
  40 #define STAT_XO         (1 << 10)       /* tx overflow */
  41 #define STAT_RU         (1 << 9)        /* rx underflow */
  42 #define STAT_RO         (1 << 8)        /* rx overflow */
  43 #define STAT_RD         (1 << 7)        /* codec ready */
  44 #define STAT_CP         (1 << 6)        /* command pending */
  45 #define STAT_TE         (1 << 4)        /* tx fifo empty */
  46 #define STAT_TF         (1 << 3)        /* tx fifo full */
  47 #define STAT_RE         (1 << 1)        /* rx fifo empty */
  48 #define STAT_RF         (1 << 0)        /* rx fifo full */
  49 #define CMD_SET_DATA(x) (((x) & 0xffff) << 16)
  50 #define CMD_GET_DATA(x) ((x) & 0xffff)
  51 #define CMD_READ        (1 << 7)
  52 #define CMD_WRITE       (0 << 7)
  53 #define CMD_IDX(x)      ((x) & 0x7f)
  54 #define EN_D            (1 << 1)        /* DISable bit */
  55 #define EN_CE           (1 << 0)        /* clock enable bit */
  56 
  57 /* how often to retry failed codec register reads/writes */
  58 #define AC97_RW_RETRIES 5
  59 
  60 #define AC97_RATES      \
  61         SNDRV_PCM_RATE_CONTINUOUS
  62 
  63 #define AC97_FMTS       \
  64         (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE)
  65 
  66 /* instance data. There can be only one, MacLeod!!!!, fortunately there IS only
  67  * once AC97C on early Alchemy chips. The newer ones aren't so lucky.
  68  */
  69 static struct au1xpsc_audio_data *ac97c_workdata;
  70 #define ac97_to_ctx(x)          ac97c_workdata
  71 
  72 static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
  73 {
  74         return __raw_readl(ctx->mmio + reg);
  75 }
  76 
  77 static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
  78 {
  79         __raw_writel(v, ctx->mmio + reg);
  80         wmb();
  81 }
  82 
  83 static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97,
  84                                           unsigned short r)
  85 {
  86         struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
  87         unsigned int tmo, retry;
  88         unsigned long data;
  89 
  90         data = ~0;
  91         retry = AC97_RW_RETRIES;
  92         do {
  93                 mutex_lock(&ctx->lock);
  94 
  95                 tmo = 6;
  96                 while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo)
  97                         udelay(21);     /* wait an ac97 frame time */
  98                 if (!tmo) {
  99                         pr_debug("ac97rd timeout #1\n");
 100                         goto next;
 101                 }
 102 
 103                 WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ);
 104 
 105                 /* stupid errata: data is only valid for 21us, so
 106                  * poll, Forrest, poll...
 107                  */
 108                 tmo = 0x10000;
 109                 while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo)
 110                         asm volatile ("nop");
 111                 data = RD(ctx, AC97_CMDRESP);
 112 
 113                 if (!tmo)
 114                         pr_debug("ac97rd timeout #2\n");
 115 
 116 next:
 117                 mutex_unlock(&ctx->lock);
 118         } while (--retry && !tmo);
 119 
 120         pr_debug("AC97RD %04x %04lx %d\n", r, data, retry);
 121 
 122         return retry ? data & 0xffff : 0xffff;
 123 }
 124 
 125 static void au1xac97c_ac97_write(struct snd_ac97 *ac97, unsigned short r,
 126                                  unsigned short v)
 127 {
 128         struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
 129         unsigned int tmo, retry;
 130 
 131         retry = AC97_RW_RETRIES;
 132         do {
 133                 mutex_lock(&ctx->lock);
 134 
 135                 for (tmo = 5; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
 136                         udelay(21);
 137                 if (!tmo) {
 138                         pr_debug("ac97wr timeout #1\n");
 139                         goto next;
 140                 }
 141 
 142                 WR(ctx, AC97_CMDRESP, CMD_WRITE | CMD_IDX(r) | CMD_SET_DATA(v));
 143 
 144                 for (tmo = 10; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--)
 145                         udelay(21);
 146                 if (!tmo)
 147                         pr_debug("ac97wr timeout #2\n");
 148 next:
 149                 mutex_unlock(&ctx->lock);
 150         } while (--retry && !tmo);
 151 
 152         pr_debug("AC97WR %04x %04x %d\n", r, v, retry);
 153 }
 154 
 155 static void au1xac97c_ac97_warm_reset(struct snd_ac97 *ac97)
 156 {
 157         struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
 158 
 159         WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG | CFG_SN);
 160         msleep(20);
 161         WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG);
 162         WR(ctx, AC97_CONFIG, ctx->cfg);
 163 }
 164 
 165 static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
 166 {
 167         struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
 168         int i;
 169 
 170         WR(ctx, AC97_CONFIG, ctx->cfg | CFG_RS);
 171         msleep(500);
 172         WR(ctx, AC97_CONFIG, ctx->cfg);
 173 
 174         /* wait for codec ready */
 175         i = 50;
 176         while (((RD(ctx, AC97_STATUS) & STAT_RD) == 0) && --i)
 177                 msleep(20);
 178         if (!i)
 179                 printk(KERN_ERR "ac97c: codec not ready after cold reset\n");
 180 }
 181 
 182 /* AC97 controller operations */
 183 static struct snd_ac97_bus_ops ac97c_bus_ops = {
 184         .read           = au1xac97c_ac97_read,
 185         .write          = au1xac97c_ac97_write,
 186         .reset          = au1xac97c_ac97_cold_reset,
 187         .warm_reset     = au1xac97c_ac97_warm_reset,
 188 };
 189 
 190 static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
 191                                  struct snd_soc_dai *dai)
 192 {
 193         struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
 194         snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
 195         return 0;
 196 }
 197 
 198 static const struct snd_soc_dai_ops alchemy_ac97c_ops = {
 199         .startup                = alchemy_ac97c_startup,
 200 };
 201 
 202 static int au1xac97c_dai_probe(struct snd_soc_dai *dai)
 203 {
 204         return ac97c_workdata ? 0 : -ENODEV;
 205 }
 206 
 207 static struct snd_soc_dai_driver au1xac97c_dai_driver = {
 208         .name                   = "alchemy-ac97c",
 209         .bus_control            = true,
 210         .probe                  = au1xac97c_dai_probe,
 211         .playback = {
 212                 .rates          = AC97_RATES,
 213                 .formats        = AC97_FMTS,
 214                 .channels_min   = 2,
 215                 .channels_max   = 2,
 216         },
 217         .capture = {
 218                 .rates          = AC97_RATES,
 219                 .formats        = AC97_FMTS,
 220                 .channels_min   = 2,
 221                 .channels_max   = 2,
 222         },
 223         .ops                    = &alchemy_ac97c_ops,
 224 };
 225 
 226 static const struct snd_soc_component_driver au1xac97c_component = {
 227         .name           = "au1xac97c",
 228 };
 229 
 230 static int au1xac97c_drvprobe(struct platform_device *pdev)
 231 {
 232         int ret;
 233         struct resource *iores, *dmares;
 234         struct au1xpsc_audio_data *ctx;
 235 
 236         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
 237         if (!ctx)
 238                 return -ENOMEM;
 239 
 240         mutex_init(&ctx->lock);
 241 
 242         iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 243         if (!iores)
 244                 return -ENODEV;
 245 
 246         if (!devm_request_mem_region(&pdev->dev, iores->start,
 247                                      resource_size(iores),
 248                                      pdev->name))
 249                 return -EBUSY;
 250 
 251         ctx->mmio = devm_ioremap_nocache(&pdev->dev, iores->start,
 252                                          resource_size(iores));
 253         if (!ctx->mmio)
 254                 return -EBUSY;
 255 
 256         dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
 257         if (!dmares)
 258                 return -EBUSY;
 259         ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;
 260 
 261         dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
 262         if (!dmares)
 263                 return -EBUSY;
 264         ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;
 265 
 266         /* switch it on */
 267         WR(ctx, AC97_ENABLE, EN_D | EN_CE);
 268         WR(ctx, AC97_ENABLE, EN_CE);
 269 
 270         ctx->cfg = CFG_RC(3) | CFG_XS(3);
 271         WR(ctx, AC97_CONFIG, ctx->cfg);
 272 
 273         platform_set_drvdata(pdev, ctx);
 274 
 275         ret = snd_soc_set_ac97_ops(&ac97c_bus_ops);
 276         if (ret)
 277                 return ret;
 278 
 279         ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component,
 280                                          &au1xac97c_dai_driver, 1);
 281         if (ret)
 282                 return ret;
 283 
 284         ac97c_workdata = ctx;
 285         return 0;
 286 }
 287 
 288 static int au1xac97c_drvremove(struct platform_device *pdev)
 289 {
 290         struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
 291 
 292         snd_soc_unregister_component(&pdev->dev);
 293 
 294         WR(ctx, AC97_ENABLE, EN_D);     /* clock off, disable */
 295 
 296         ac97c_workdata = NULL;  /* MDEV */
 297 
 298         return 0;
 299 }
 300 
 301 #ifdef CONFIG_PM
 302 static int au1xac97c_drvsuspend(struct device *dev)
 303 {
 304         struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
 305 
 306         WR(ctx, AC97_ENABLE, EN_D);     /* clock off, disable */
 307 
 308         return 0;
 309 }
 310 
 311 static int au1xac97c_drvresume(struct device *dev)
 312 {
 313         struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);
 314 
 315         WR(ctx, AC97_ENABLE, EN_D | EN_CE);
 316         WR(ctx, AC97_ENABLE, EN_CE);
 317         WR(ctx, AC97_CONFIG, ctx->cfg);
 318 
 319         return 0;
 320 }
 321 
 322 static const struct dev_pm_ops au1xpscac97_pmops = {
 323         .suspend        = au1xac97c_drvsuspend,
 324         .resume         = au1xac97c_drvresume,
 325 };
 326 
 327 #define AU1XPSCAC97_PMOPS (&au1xpscac97_pmops)
 328 
 329 #else
 330 
 331 #define AU1XPSCAC97_PMOPS NULL
 332 
 333 #endif
 334 
 335 static struct platform_driver au1xac97c_driver = {
 336         .driver = {
 337                 .name   = "alchemy-ac97c",
 338                 .pm     = AU1XPSCAC97_PMOPS,
 339         },
 340         .probe          = au1xac97c_drvprobe,
 341         .remove         = au1xac97c_drvremove,
 342 };
 343 
 344 module_platform_driver(au1xac97c_driver);
 345 
 346 MODULE_LICENSE("GPL");
 347 MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
 348 MODULE_AUTHOR("Manuel Lauss");

/* [<][>][^][v][top][bottom][index][help] */