linux/sound/mips/sgio2audio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *   Sound driver for Silicon Graphics O2 Workstations A/V board audio.
   4 *
   5 *   Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
   6 *   Copyright 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
   7 *   Mxier part taken from mace_audio.c:
   8 *   Copyright 2007 Thorben Jändling <tj.trevelyan@gmail.com>
   9 */
  10
  11#include <linux/init.h>
  12#include <linux/delay.h>
  13#include <linux/spinlock.h>
  14#include <linux/interrupt.h>
  15#include <linux/dma-mapping.h>
  16#include <linux/platform_device.h>
  17#include <linux/io.h>
  18#include <linux/slab.h>
  19#include <linux/module.h>
  20
  21#include <asm/ip32/ip32_ints.h>
  22#include <asm/ip32/mace.h>
  23
  24#include <sound/core.h>
  25#include <sound/control.h>
  26#include <sound/pcm.h>
  27#define SNDRV_GET_ID
  28#include <sound/initval.h>
  29#include <sound/ad1843.h>
  30
  31
  32MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org>");
  33MODULE_DESCRIPTION("SGI O2 Audio");
  34MODULE_LICENSE("GPL");
  35
  36static int index = SNDRV_DEFAULT_IDX1;  /* Index 0-MAX */
  37static char *id = SNDRV_DEFAULT_STR1;   /* ID for this card */
  38
  39module_param(index, int, 0444);
  40MODULE_PARM_DESC(index, "Index value for SGI O2 soundcard.");
  41module_param(id, charp, 0444);
  42MODULE_PARM_DESC(id, "ID string for SGI O2 soundcard.");
  43
  44
  45#define AUDIO_CONTROL_RESET              BIT(0) /* 1: reset audio interface */
  46#define AUDIO_CONTROL_CODEC_PRESENT      BIT(1) /* 1: codec detected */
  47
  48#define CODEC_CONTROL_WORD_SHIFT        0
  49#define CODEC_CONTROL_READ              BIT(16)
  50#define CODEC_CONTROL_ADDRESS_SHIFT     17
  51
  52#define CHANNEL_CONTROL_RESET           BIT(10) /* 1: reset channel */
  53#define CHANNEL_DMA_ENABLE              BIT(9)  /* 1: enable DMA transfer */
  54#define CHANNEL_INT_THRESHOLD_DISABLED  (0 << 5) /* interrupt disabled */
  55#define CHANNEL_INT_THRESHOLD_25        (1 << 5) /* int on buffer >25% full */
  56#define CHANNEL_INT_THRESHOLD_50        (2 << 5) /* int on buffer >50% full */
  57#define CHANNEL_INT_THRESHOLD_75        (3 << 5) /* int on buffer >75% full */
  58#define CHANNEL_INT_THRESHOLD_EMPTY     (4 << 5) /* int on buffer empty */
  59#define CHANNEL_INT_THRESHOLD_NOT_EMPTY (5 << 5) /* int on buffer !empty */
  60#define CHANNEL_INT_THRESHOLD_FULL      (6 << 5) /* int on buffer empty */
  61#define CHANNEL_INT_THRESHOLD_NOT_FULL  (7 << 5) /* int on buffer !empty */
  62
  63#define CHANNEL_RING_SHIFT              12
  64#define CHANNEL_RING_SIZE               (1 << CHANNEL_RING_SHIFT)
  65#define CHANNEL_RING_MASK               (CHANNEL_RING_SIZE - 1)
  66
  67#define CHANNEL_LEFT_SHIFT 40
  68#define CHANNEL_RIGHT_SHIFT 8
  69
  70struct snd_sgio2audio_chan {
  71        int idx;
  72        struct snd_pcm_substream *substream;
  73        int pos;
  74        snd_pcm_uframes_t size;
  75        spinlock_t lock;
  76};
  77
  78/* definition of the chip-specific record */
  79struct snd_sgio2audio {
  80        struct snd_card *card;
  81
  82        /* codec */
  83        struct snd_ad1843 ad1843;
  84        spinlock_t ad1843_lock;
  85
  86        /* channels */
  87        struct snd_sgio2audio_chan channel[3];
  88
  89        /* resources */
  90        void *ring_base;
  91        dma_addr_t ring_base_dma;
  92};
  93
  94/* AD1843 access */
  95
  96/*
  97 * read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
  98 *
  99 * Returns unsigned register value on success, -errno on failure.
 100 */
 101static int read_ad1843_reg(void *priv, int reg)
 102{
 103        struct snd_sgio2audio *chip = priv;
 104        int val;
 105        unsigned long flags;
 106
 107        spin_lock_irqsave(&chip->ad1843_lock, flags);
 108
 109        writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
 110               CODEC_CONTROL_READ, &mace->perif.audio.codec_control);
 111        wmb();
 112        val = readq(&mace->perif.audio.codec_control); /* flush bus */
 113        udelay(200);
 114
 115        val = readq(&mace->perif.audio.codec_read);
 116
 117        spin_unlock_irqrestore(&chip->ad1843_lock, flags);
 118        return val;
 119}
 120
 121/*
 122 * write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
 123 */
 124static int write_ad1843_reg(void *priv, int reg, int word)
 125{
 126        struct snd_sgio2audio *chip = priv;
 127        int val;
 128        unsigned long flags;
 129
 130        spin_lock_irqsave(&chip->ad1843_lock, flags);
 131
 132        writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
 133               (word << CODEC_CONTROL_WORD_SHIFT),
 134               &mace->perif.audio.codec_control);
 135        wmb();
 136        val = readq(&mace->perif.audio.codec_control); /* flush bus */
 137        udelay(200);
 138
 139        spin_unlock_irqrestore(&chip->ad1843_lock, flags);
 140        return 0;
 141}
 142
 143static int sgio2audio_gain_info(struct snd_kcontrol *kcontrol,
 144                               struct snd_ctl_elem_info *uinfo)
 145{
 146        struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
 147
 148        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 149        uinfo->count = 2;
 150        uinfo->value.integer.min = 0;
 151        uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843,
 152                                             (int)kcontrol->private_value);
 153        return 0;
 154}
 155
 156static int sgio2audio_gain_get(struct snd_kcontrol *kcontrol,
 157                               struct snd_ctl_elem_value *ucontrol)
 158{
 159        struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
 160        int vol;
 161
 162        vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value);
 163
 164        ucontrol->value.integer.value[0] = (vol >> 8) & 0xFF;
 165        ucontrol->value.integer.value[1] = vol & 0xFF;
 166
 167        return 0;
 168}
 169
 170static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol,
 171                        struct snd_ctl_elem_value *ucontrol)
 172{
 173        struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
 174        int newvol, oldvol;
 175
 176        oldvol = ad1843_get_gain(&chip->ad1843, kcontrol->private_value);
 177        newvol = (ucontrol->value.integer.value[0] << 8) |
 178                ucontrol->value.integer.value[1];
 179
 180        newvol = ad1843_set_gain(&chip->ad1843, kcontrol->private_value,
 181                newvol);
 182
 183        return newvol != oldvol;
 184}
 185
 186static int sgio2audio_source_info(struct snd_kcontrol *kcontrol,
 187                               struct snd_ctl_elem_info *uinfo)
 188{
 189        static const char * const texts[3] = {
 190                "Cam Mic", "Mic", "Line"
 191        };
 192        return snd_ctl_enum_info(uinfo, 1, 3, texts);
 193}
 194
 195static int sgio2audio_source_get(struct snd_kcontrol *kcontrol,
 196                               struct snd_ctl_elem_value *ucontrol)
 197{
 198        struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
 199
 200        ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843);
 201        return 0;
 202}
 203
 204static int sgio2audio_source_put(struct snd_kcontrol *kcontrol,
 205                        struct snd_ctl_elem_value *ucontrol)
 206{
 207        struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
 208        int newsrc, oldsrc;
 209
 210        oldsrc = ad1843_get_recsrc(&chip->ad1843);
 211        newsrc = ad1843_set_recsrc(&chip->ad1843,
 212                                   ucontrol->value.enumerated.item[0]);
 213
 214        return newsrc != oldsrc;
 215}
 216
 217/* dac1/pcm0 mixer control */
 218static const struct snd_kcontrol_new sgio2audio_ctrl_pcm0 = {
 219        .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 220        .name           = "PCM Playback Volume",
 221        .index          = 0,
 222        .access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 223        .private_value  = AD1843_GAIN_PCM_0,
 224        .info           = sgio2audio_gain_info,
 225        .get            = sgio2audio_gain_get,
 226        .put            = sgio2audio_gain_put,
 227};
 228
 229/* dac2/pcm1 mixer control */
 230static const struct snd_kcontrol_new sgio2audio_ctrl_pcm1 = {
 231        .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 232        .name           = "PCM Playback Volume",
 233        .index          = 1,
 234        .access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 235        .private_value  = AD1843_GAIN_PCM_1,
 236        .info           = sgio2audio_gain_info,
 237        .get            = sgio2audio_gain_get,
 238        .put            = sgio2audio_gain_put,
 239};
 240
 241/* record level mixer control */
 242static const struct snd_kcontrol_new sgio2audio_ctrl_reclevel = {
 243        .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 244        .name           = "Capture Volume",
 245        .access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 246        .private_value  = AD1843_GAIN_RECLEV,
 247        .info           = sgio2audio_gain_info,
 248        .get            = sgio2audio_gain_get,
 249        .put            = sgio2audio_gain_put,
 250};
 251
 252/* record level source control */
 253static const struct snd_kcontrol_new sgio2audio_ctrl_recsource = {
 254        .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 255        .name           = "Capture Source",
 256        .access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 257        .info           = sgio2audio_source_info,
 258        .get            = sgio2audio_source_get,
 259        .put            = sgio2audio_source_put,
 260};
 261
 262/* line mixer control */
 263static const struct snd_kcontrol_new sgio2audio_ctrl_line = {
 264        .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 265        .name           = "Line Playback Volume",
 266        .index          = 0,
 267        .access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 268        .private_value  = AD1843_GAIN_LINE,
 269        .info           = sgio2audio_gain_info,
 270        .get            = sgio2audio_gain_get,
 271        .put            = sgio2audio_gain_put,
 272};
 273
 274/* cd mixer control */
 275static const struct snd_kcontrol_new sgio2audio_ctrl_cd = {
 276        .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 277        .name           = "Line Playback Volume",
 278        .index          = 1,
 279        .access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 280        .private_value  = AD1843_GAIN_LINE_2,
 281        .info           = sgio2audio_gain_info,
 282        .get            = sgio2audio_gain_get,
 283        .put            = sgio2audio_gain_put,
 284};
 285
 286/* mic mixer control */
 287static const struct snd_kcontrol_new sgio2audio_ctrl_mic = {
 288        .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 289        .name           = "Mic Playback Volume",
 290        .access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 291        .private_value  = AD1843_GAIN_MIC,
 292        .info           = sgio2audio_gain_info,
 293        .get            = sgio2audio_gain_get,
 294        .put            = sgio2audio_gain_put,
 295};
 296
 297
 298static int snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip)
 299{
 300        int err;
 301
 302        err = snd_ctl_add(chip->card,
 303                          snd_ctl_new1(&sgio2audio_ctrl_pcm0, chip));
 304        if (err < 0)
 305                return err;
 306
 307        err = snd_ctl_add(chip->card,
 308                          snd_ctl_new1(&sgio2audio_ctrl_pcm1, chip));
 309        if (err < 0)
 310                return err;
 311
 312        err = snd_ctl_add(chip->card,
 313                          snd_ctl_new1(&sgio2audio_ctrl_reclevel, chip));
 314        if (err < 0)
 315                return err;
 316
 317        err = snd_ctl_add(chip->card,
 318                          snd_ctl_new1(&sgio2audio_ctrl_recsource, chip));
 319        if (err < 0)
 320                return err;
 321        err = snd_ctl_add(chip->card,
 322                          snd_ctl_new1(&sgio2audio_ctrl_line, chip));
 323        if (err < 0)
 324                return err;
 325
 326        err = snd_ctl_add(chip->card,
 327                          snd_ctl_new1(&sgio2audio_ctrl_cd, chip));
 328        if (err < 0)
 329                return err;
 330
 331        err = snd_ctl_add(chip->card,
 332                          snd_ctl_new1(&sgio2audio_ctrl_mic, chip));
 333        if (err < 0)
 334                return err;
 335
 336        return 0;
 337}
 338
 339/* low-level audio interface DMA */
 340
 341/* get data out of bounce buffer, count must be a multiple of 32 */
 342/* returns 1 if a period has elapsed */
 343static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip,
 344                                        unsigned int ch, unsigned int count)
 345{
 346        int ret;
 347        unsigned long src_base, src_pos, dst_mask;
 348        unsigned char *dst_base;
 349        int dst_pos;
 350        u64 *src;
 351        s16 *dst;
 352        u64 x;
 353        unsigned long flags;
 354        struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
 355
 356        spin_lock_irqsave(&chip->channel[ch].lock, flags);
 357
 358        src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT);
 359        src_pos = readq(&mace->perif.audio.chan[ch].read_ptr);
 360        dst_base = runtime->dma_area;
 361        dst_pos = chip->channel[ch].pos;
 362        dst_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
 363
 364        /* check if a period has elapsed */
 365        chip->channel[ch].size += (count >> 3); /* in frames */
 366        ret = chip->channel[ch].size >= runtime->period_size;
 367        chip->channel[ch].size %= runtime->period_size;
 368
 369        while (count) {
 370                src = (u64 *)(src_base + src_pos);
 371                dst = (s16 *)(dst_base + dst_pos);
 372
 373                x = *src;
 374                dst[0] = (x >> CHANNEL_LEFT_SHIFT) & 0xffff;
 375                dst[1] = (x >> CHANNEL_RIGHT_SHIFT) & 0xffff;
 376
 377                src_pos = (src_pos + sizeof(u64)) & CHANNEL_RING_MASK;
 378                dst_pos = (dst_pos + 2 * sizeof(s16)) & dst_mask;
 379                count -= sizeof(u64);
 380        }
 381
 382        writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr); /* in bytes */
 383        chip->channel[ch].pos = dst_pos;
 384
 385        spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
 386        return ret;
 387}
 388
 389/* put some DMA data in bounce buffer, count must be a multiple of 32 */
 390/* returns 1 if a period has elapsed */
 391static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip,
 392                                        unsigned int ch, unsigned int count)
 393{
 394        int ret;
 395        s64 l, r;
 396        unsigned long dst_base, dst_pos, src_mask;
 397        unsigned char *src_base;
 398        int src_pos;
 399        u64 *dst;
 400        s16 *src;
 401        unsigned long flags;
 402        struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
 403
 404        spin_lock_irqsave(&chip->channel[ch].lock, flags);
 405
 406        dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT);
 407        dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr);
 408        src_base = runtime->dma_area;
 409        src_pos = chip->channel[ch].pos;
 410        src_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
 411
 412        /* check if a period has elapsed */
 413        chip->channel[ch].size += (count >> 3); /* in frames */
 414        ret = chip->channel[ch].size >= runtime->period_size;
 415        chip->channel[ch].size %= runtime->period_size;
 416
 417        while (count) {
 418                src = (s16 *)(src_base + src_pos);
 419                dst = (u64 *)(dst_base + dst_pos);
 420
 421                l = src[0]; /* sign extend */
 422                r = src[1]; /* sign extend */
 423
 424                *dst = ((l & 0x00ffffff) << CHANNEL_LEFT_SHIFT) |
 425                        ((r & 0x00ffffff) << CHANNEL_RIGHT_SHIFT);
 426
 427                dst_pos = (dst_pos + sizeof(u64)) & CHANNEL_RING_MASK;
 428                src_pos = (src_pos + 2 * sizeof(s16)) & src_mask;
 429                count -= sizeof(u64);
 430        }
 431
 432        writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr); /* in bytes */
 433        chip->channel[ch].pos = src_pos;
 434
 435        spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
 436        return ret;
 437}
 438
 439static int snd_sgio2audio_dma_start(struct snd_pcm_substream *substream)
 440{
 441        struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
 442        struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
 443        int ch = chan->idx;
 444
 445        /* reset DMA channel */
 446        writeq(CHANNEL_CONTROL_RESET, &mace->perif.audio.chan[ch].control);
 447        udelay(10);
 448        writeq(0, &mace->perif.audio.chan[ch].control);
 449
 450        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 451                /* push a full buffer */
 452                snd_sgio2audio_dma_push_frag(chip, ch, CHANNEL_RING_SIZE - 32);
 453        }
 454        /* set DMA to wake on 50% empty and enable interrupt */
 455        writeq(CHANNEL_DMA_ENABLE | CHANNEL_INT_THRESHOLD_50,
 456               &mace->perif.audio.chan[ch].control);
 457        return 0;
 458}
 459
 460static int snd_sgio2audio_dma_stop(struct snd_pcm_substream *substream)
 461{
 462        struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
 463
 464        writeq(0, &mace->perif.audio.chan[chan->idx].control);
 465        return 0;
 466}
 467
 468static irqreturn_t snd_sgio2audio_dma_in_isr(int irq, void *dev_id)
 469{
 470        struct snd_sgio2audio_chan *chan = dev_id;
 471        struct snd_pcm_substream *substream;
 472        struct snd_sgio2audio *chip;
 473        int count, ch;
 474
 475        substream = chan->substream;
 476        chip = snd_pcm_substream_chip(substream);
 477        ch = chan->idx;
 478
 479        /* empty the ring */
 480        count = CHANNEL_RING_SIZE -
 481                readq(&mace->perif.audio.chan[ch].depth) - 32;
 482        if (snd_sgio2audio_dma_pull_frag(chip, ch, count))
 483                snd_pcm_period_elapsed(substream);
 484
 485        return IRQ_HANDLED;
 486}
 487
 488static irqreturn_t snd_sgio2audio_dma_out_isr(int irq, void *dev_id)
 489{
 490        struct snd_sgio2audio_chan *chan = dev_id;
 491        struct snd_pcm_substream *substream;
 492        struct snd_sgio2audio *chip;
 493        int count, ch;
 494
 495        substream = chan->substream;
 496        chip = snd_pcm_substream_chip(substream);
 497        ch = chan->idx;
 498        /* fill the ring */
 499        count = CHANNEL_RING_SIZE -
 500                readq(&mace->perif.audio.chan[ch].depth) - 32;
 501        if (snd_sgio2audio_dma_push_frag(chip, ch, count))
 502                snd_pcm_period_elapsed(substream);
 503
 504        return IRQ_HANDLED;
 505}
 506
 507static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id)
 508{
 509        struct snd_sgio2audio_chan *chan = dev_id;
 510        struct snd_pcm_substream *substream;
 511
 512        substream = chan->substream;
 513        snd_sgio2audio_dma_stop(substream);
 514        snd_sgio2audio_dma_start(substream);
 515        return IRQ_HANDLED;
 516}
 517
 518/* PCM part */
 519/* PCM hardware definition */
 520static const struct snd_pcm_hardware snd_sgio2audio_pcm_hw = {
 521        .info = (SNDRV_PCM_INFO_MMAP |
 522                 SNDRV_PCM_INFO_MMAP_VALID |
 523                 SNDRV_PCM_INFO_INTERLEAVED |
 524                 SNDRV_PCM_INFO_BLOCK_TRANSFER),
 525        .formats =          SNDRV_PCM_FMTBIT_S16_BE,
 526        .rates =            SNDRV_PCM_RATE_8000_48000,
 527        .rate_min =         8000,
 528        .rate_max =         48000,
 529        .channels_min =     2,
 530        .channels_max =     2,
 531        .buffer_bytes_max = 65536,
 532        .period_bytes_min = 32768,
 533        .period_bytes_max = 65536,
 534        .periods_min =      1,
 535        .periods_max =      1024,
 536};
 537
 538/* PCM playback open callback */
 539static int snd_sgio2audio_playback1_open(struct snd_pcm_substream *substream)
 540{
 541        struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
 542        struct snd_pcm_runtime *runtime = substream->runtime;
 543
 544        runtime->hw = snd_sgio2audio_pcm_hw;
 545        runtime->private_data = &chip->channel[1];
 546        return 0;
 547}
 548
 549static int snd_sgio2audio_playback2_open(struct snd_pcm_substream *substream)
 550{
 551        struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
 552        struct snd_pcm_runtime *runtime = substream->runtime;
 553
 554        runtime->hw = snd_sgio2audio_pcm_hw;
 555        runtime->private_data = &chip->channel[2];
 556        return 0;
 557}
 558
 559/* PCM capture open callback */
 560static int snd_sgio2audio_capture_open(struct snd_pcm_substream *substream)
 561{
 562        struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
 563        struct snd_pcm_runtime *runtime = substream->runtime;
 564
 565        runtime->hw = snd_sgio2audio_pcm_hw;
 566        runtime->private_data = &chip->channel[0];
 567        return 0;
 568}
 569
 570/* PCM close callback */
 571static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
 572{
 573        struct snd_pcm_runtime *runtime = substream->runtime;
 574
 575        runtime->private_data = NULL;
 576        return 0;
 577}
 578
 579/* prepare callback */
 580static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream)
 581{
 582        struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
 583        struct snd_pcm_runtime *runtime = substream->runtime;
 584        struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
 585        int ch = chan->idx;
 586        unsigned long flags;
 587
 588        spin_lock_irqsave(&chip->channel[ch].lock, flags);
 589
 590        /* Setup the pseudo-dma transfer pointers.  */
 591        chip->channel[ch].pos = 0;
 592        chip->channel[ch].size = 0;
 593        chip->channel[ch].substream = substream;
 594
 595        /* set AD1843 format */
 596        /* hardware format is always S16_LE */
 597        switch (substream->stream) {
 598        case SNDRV_PCM_STREAM_PLAYBACK:
 599                ad1843_setup_dac(&chip->ad1843,
 600                                 ch - 1,
 601                                 runtime->rate,
 602                                 SNDRV_PCM_FORMAT_S16_LE,
 603                                 runtime->channels);
 604                break;
 605        case SNDRV_PCM_STREAM_CAPTURE:
 606                ad1843_setup_adc(&chip->ad1843,
 607                                 runtime->rate,
 608                                 SNDRV_PCM_FORMAT_S16_LE,
 609                                 runtime->channels);
 610                break;
 611        }
 612        spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
 613        return 0;
 614}
 615
 616/* trigger callback */
 617static int snd_sgio2audio_pcm_trigger(struct snd_pcm_substream *substream,
 618                                      int cmd)
 619{
 620        switch (cmd) {
 621        case SNDRV_PCM_TRIGGER_START:
 622                /* start the PCM engine */
 623                snd_sgio2audio_dma_start(substream);
 624                break;
 625        case SNDRV_PCM_TRIGGER_STOP:
 626                /* stop the PCM engine */
 627                snd_sgio2audio_dma_stop(substream);
 628                break;
 629        default:
 630                return -EINVAL;
 631        }
 632        return 0;
 633}
 634
 635/* pointer callback */
 636static snd_pcm_uframes_t
 637snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
 638{
 639        struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
 640        struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
 641
 642        /* get the current hardware pointer */
 643        return bytes_to_frames(substream->runtime,
 644                               chip->channel[chan->idx].pos);
 645}
 646
 647/* operators */
 648static const struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
 649        .open =        snd_sgio2audio_playback1_open,
 650        .close =       snd_sgio2audio_pcm_close,
 651        .prepare =     snd_sgio2audio_pcm_prepare,
 652        .trigger =     snd_sgio2audio_pcm_trigger,
 653        .pointer =     snd_sgio2audio_pcm_pointer,
 654};
 655
 656static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
 657        .open =        snd_sgio2audio_playback2_open,
 658        .close =       snd_sgio2audio_pcm_close,
 659        .prepare =     snd_sgio2audio_pcm_prepare,
 660        .trigger =     snd_sgio2audio_pcm_trigger,
 661        .pointer =     snd_sgio2audio_pcm_pointer,
 662};
 663
 664static const struct snd_pcm_ops snd_sgio2audio_capture_ops = {
 665        .open =        snd_sgio2audio_capture_open,
 666        .close =       snd_sgio2audio_pcm_close,
 667        .prepare =     snd_sgio2audio_pcm_prepare,
 668        .trigger =     snd_sgio2audio_pcm_trigger,
 669        .pointer =     snd_sgio2audio_pcm_pointer,
 670};
 671
 672/*
 673 *  definitions of capture are omitted here...
 674 */
 675
 676/* create a pcm device */
 677static int snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip)
 678{
 679        struct snd_pcm *pcm;
 680        int err;
 681
 682        /* create first pcm device with one outputs and one input */
 683        err = snd_pcm_new(chip->card, "SGI O2 Audio", 0, 1, 1, &pcm);
 684        if (err < 0)
 685                return err;
 686
 687        pcm->private_data = chip;
 688        strcpy(pcm->name, "SGI O2 DAC1");
 689
 690        /* set operators */
 691        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 692                        &snd_sgio2audio_playback1_ops);
 693        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
 694                        &snd_sgio2audio_capture_ops);
 695        snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
 696
 697        /* create second  pcm device with one outputs and no input */
 698        err = snd_pcm_new(chip->card, "SGI O2 Audio", 1, 1, 0, &pcm);
 699        if (err < 0)
 700                return err;
 701
 702        pcm->private_data = chip;
 703        strcpy(pcm->name, "SGI O2 DAC2");
 704
 705        /* set operators */
 706        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 707                        &snd_sgio2audio_playback2_ops);
 708        snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
 709
 710        return 0;
 711}
 712
 713static struct {
 714        int idx;
 715        int irq;
 716        irqreturn_t (*isr)(int, void *);
 717        const char *desc;
 718} snd_sgio2_isr_table[] = {
 719        {
 720                .idx = 0,
 721                .irq = MACEISA_AUDIO1_DMAT_IRQ,
 722                .isr = snd_sgio2audio_dma_in_isr,
 723                .desc = "Capture DMA Channel 0"
 724        }, {
 725                .idx = 0,
 726                .irq = MACEISA_AUDIO1_OF_IRQ,
 727                .isr = snd_sgio2audio_error_isr,
 728                .desc = "Capture Overflow"
 729        }, {
 730                .idx = 1,
 731                .irq = MACEISA_AUDIO2_DMAT_IRQ,
 732                .isr = snd_sgio2audio_dma_out_isr,
 733                .desc = "Playback DMA Channel 1"
 734        }, {
 735                .idx = 1,
 736                .irq = MACEISA_AUDIO2_MERR_IRQ,
 737                .isr = snd_sgio2audio_error_isr,
 738                .desc = "Memory Error Channel 1"
 739        }, {
 740                .idx = 2,
 741                .irq = MACEISA_AUDIO3_DMAT_IRQ,
 742                .isr = snd_sgio2audio_dma_out_isr,
 743                .desc = "Playback DMA Channel 2"
 744        }, {
 745                .idx = 2,
 746                .irq = MACEISA_AUDIO3_MERR_IRQ,
 747                .isr = snd_sgio2audio_error_isr,
 748                .desc = "Memory Error Channel 2"
 749        }
 750};
 751
 752/* ALSA driver */
 753
 754static int snd_sgio2audio_free(struct snd_sgio2audio *chip)
 755{
 756        int i;
 757
 758        /* reset interface */
 759        writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
 760        udelay(1);
 761        writeq(0, &mace->perif.audio.control);
 762
 763        /* release IRQ's */
 764        for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++)
 765                free_irq(snd_sgio2_isr_table[i].irq,
 766                         &chip->channel[snd_sgio2_isr_table[i].idx]);
 767
 768        dma_free_coherent(chip->card->dev, MACEISA_RINGBUFFERS_SIZE,
 769                          chip->ring_base, chip->ring_base_dma);
 770
 771        /* release card data */
 772        kfree(chip);
 773        return 0;
 774}
 775
 776static int snd_sgio2audio_dev_free(struct snd_device *device)
 777{
 778        struct snd_sgio2audio *chip = device->device_data;
 779
 780        return snd_sgio2audio_free(chip);
 781}
 782
 783static const struct snd_device_ops ops = {
 784        .dev_free = snd_sgio2audio_dev_free,
 785};
 786
 787static int snd_sgio2audio_create(struct snd_card *card,
 788                                 struct snd_sgio2audio **rchip)
 789{
 790        struct snd_sgio2audio *chip;
 791        int i, err;
 792
 793        *rchip = NULL;
 794
 795        /* check if a codec is attached to the interface */
 796        /* (Audio or Audio/Video board present) */
 797        if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT))
 798                return -ENOENT;
 799
 800        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 801        if (chip == NULL)
 802                return -ENOMEM;
 803
 804        chip->card = card;
 805
 806        chip->ring_base = dma_alloc_coherent(card->dev,
 807                                             MACEISA_RINGBUFFERS_SIZE,
 808                                             &chip->ring_base_dma, GFP_KERNEL);
 809        if (chip->ring_base == NULL) {
 810                printk(KERN_ERR
 811                       "sgio2audio: could not allocate ring buffers\n");
 812                kfree(chip);
 813                return -ENOMEM;
 814        }
 815
 816        spin_lock_init(&chip->ad1843_lock);
 817
 818        /* initialize channels */
 819        for (i = 0; i < 3; i++) {
 820                spin_lock_init(&chip->channel[i].lock);
 821                chip->channel[i].idx = i;
 822        }
 823
 824        /* allocate IRQs */
 825        for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) {
 826                if (request_irq(snd_sgio2_isr_table[i].irq,
 827                                snd_sgio2_isr_table[i].isr,
 828                                0,
 829                                snd_sgio2_isr_table[i].desc,
 830                                &chip->channel[snd_sgio2_isr_table[i].idx])) {
 831                        snd_sgio2audio_free(chip);
 832                        printk(KERN_ERR "sgio2audio: cannot allocate irq %d\n",
 833                               snd_sgio2_isr_table[i].irq);
 834                        return -EBUSY;
 835                }
 836        }
 837
 838        /* reset the interface */
 839        writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
 840        udelay(1);
 841        writeq(0, &mace->perif.audio.control);
 842        msleep_interruptible(1); /* give time to recover */
 843
 844        /* set ring base */
 845        writeq(chip->ring_base_dma, &mace->perif.ctrl.ringbase);
 846
 847        /* attach the AD1843 codec */
 848        chip->ad1843.read = read_ad1843_reg;
 849        chip->ad1843.write = write_ad1843_reg;
 850        chip->ad1843.chip = chip;
 851
 852        /* initialize the AD1843 codec */
 853        err = ad1843_init(&chip->ad1843);
 854        if (err < 0) {
 855                snd_sgio2audio_free(chip);
 856                return err;
 857        }
 858
 859        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
 860        if (err < 0) {
 861                snd_sgio2audio_free(chip);
 862                return err;
 863        }
 864        *rchip = chip;
 865        return 0;
 866}
 867
 868static int snd_sgio2audio_probe(struct platform_device *pdev)
 869{
 870        struct snd_card *card;
 871        struct snd_sgio2audio *chip;
 872        int err;
 873
 874        err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
 875        if (err < 0)
 876                return err;
 877
 878        err = snd_sgio2audio_create(card, &chip);
 879        if (err < 0) {
 880                snd_card_free(card);
 881                return err;
 882        }
 883
 884        err = snd_sgio2audio_new_pcm(chip);
 885        if (err < 0) {
 886                snd_card_free(card);
 887                return err;
 888        }
 889        err = snd_sgio2audio_new_mixer(chip);
 890        if (err < 0) {
 891                snd_card_free(card);
 892                return err;
 893        }
 894
 895        strcpy(card->driver, "SGI O2 Audio");
 896        strcpy(card->shortname, "SGI O2 Audio");
 897        sprintf(card->longname, "%s irq %i-%i",
 898                card->shortname,
 899                MACEISA_AUDIO1_DMAT_IRQ,
 900                MACEISA_AUDIO3_MERR_IRQ);
 901
 902        err = snd_card_register(card);
 903        if (err < 0) {
 904                snd_card_free(card);
 905                return err;
 906        }
 907        platform_set_drvdata(pdev, card);
 908        return 0;
 909}
 910
 911static int snd_sgio2audio_remove(struct platform_device *pdev)
 912{
 913        struct snd_card *card = platform_get_drvdata(pdev);
 914
 915        snd_card_free(card);
 916        return 0;
 917}
 918
 919static struct platform_driver sgio2audio_driver = {
 920        .probe  = snd_sgio2audio_probe,
 921        .remove = snd_sgio2audio_remove,
 922        .driver = {
 923                .name   = "sgio2audio",
 924        }
 925};
 926
 927module_platform_driver(sgio2audio_driver);
 928