0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/init.h>
0012 #include <linux/delay.h>
0013 #include <linux/spinlock.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/dma-mapping.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/io.h>
0018 #include <linux/slab.h>
0019 #include <linux/module.h>
0020
0021 #include <asm/ip32/ip32_ints.h>
0022 #include <asm/ip32/mace.h>
0023
0024 #include <sound/core.h>
0025 #include <sound/control.h>
0026 #include <sound/pcm.h>
0027 #define SNDRV_GET_ID
0028 #include <sound/initval.h>
0029 #include <sound/ad1843.h>
0030
0031
0032 MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org>");
0033 MODULE_DESCRIPTION("SGI O2 Audio");
0034 MODULE_LICENSE("GPL");
0035
0036 static int index = SNDRV_DEFAULT_IDX1;
0037 static char *id = SNDRV_DEFAULT_STR1;
0038
0039 module_param(index, int, 0444);
0040 MODULE_PARM_DESC(index, "Index value for SGI O2 soundcard.");
0041 module_param(id, charp, 0444);
0042 MODULE_PARM_DESC(id, "ID string for SGI O2 soundcard.");
0043
0044
0045 #define AUDIO_CONTROL_RESET BIT(0)
0046 #define AUDIO_CONTROL_CODEC_PRESENT BIT(1)
0047
0048 #define CODEC_CONTROL_WORD_SHIFT 0
0049 #define CODEC_CONTROL_READ BIT(16)
0050 #define CODEC_CONTROL_ADDRESS_SHIFT 17
0051
0052 #define CHANNEL_CONTROL_RESET BIT(10)
0053 #define CHANNEL_DMA_ENABLE BIT(9)
0054 #define CHANNEL_INT_THRESHOLD_DISABLED (0 << 5)
0055 #define CHANNEL_INT_THRESHOLD_25 (1 << 5)
0056 #define CHANNEL_INT_THRESHOLD_50 (2 << 5)
0057 #define CHANNEL_INT_THRESHOLD_75 (3 << 5)
0058 #define CHANNEL_INT_THRESHOLD_EMPTY (4 << 5)
0059 #define CHANNEL_INT_THRESHOLD_NOT_EMPTY (5 << 5)
0060 #define CHANNEL_INT_THRESHOLD_FULL (6 << 5)
0061 #define CHANNEL_INT_THRESHOLD_NOT_FULL (7 << 5)
0062
0063 #define CHANNEL_RING_SHIFT 12
0064 #define CHANNEL_RING_SIZE (1 << CHANNEL_RING_SHIFT)
0065 #define CHANNEL_RING_MASK (CHANNEL_RING_SIZE - 1)
0066
0067 #define CHANNEL_LEFT_SHIFT 40
0068 #define CHANNEL_RIGHT_SHIFT 8
0069
0070 struct snd_sgio2audio_chan {
0071 int idx;
0072 struct snd_pcm_substream *substream;
0073 int pos;
0074 snd_pcm_uframes_t size;
0075 spinlock_t lock;
0076 };
0077
0078
0079 struct snd_sgio2audio {
0080 struct snd_card *card;
0081
0082
0083 struct snd_ad1843 ad1843;
0084 spinlock_t ad1843_lock;
0085
0086
0087 struct snd_sgio2audio_chan channel[3];
0088
0089
0090 void *ring_base;
0091 dma_addr_t ring_base_dma;
0092 };
0093
0094
0095
0096
0097
0098
0099
0100
0101 static int read_ad1843_reg(void *priv, int reg)
0102 {
0103 struct snd_sgio2audio *chip = priv;
0104 int val;
0105 unsigned long flags;
0106
0107 spin_lock_irqsave(&chip->ad1843_lock, flags);
0108
0109 writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
0110 CODEC_CONTROL_READ, &mace->perif.audio.codec_control);
0111 wmb();
0112 val = readq(&mace->perif.audio.codec_control);
0113 udelay(200);
0114
0115 val = readq(&mace->perif.audio.codec_read);
0116
0117 spin_unlock_irqrestore(&chip->ad1843_lock, flags);
0118 return val;
0119 }
0120
0121
0122
0123
0124 static int write_ad1843_reg(void *priv, int reg, int word)
0125 {
0126 struct snd_sgio2audio *chip = priv;
0127 int val;
0128 unsigned long flags;
0129
0130 spin_lock_irqsave(&chip->ad1843_lock, flags);
0131
0132 writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
0133 (word << CODEC_CONTROL_WORD_SHIFT),
0134 &mace->perif.audio.codec_control);
0135 wmb();
0136 val = readq(&mace->perif.audio.codec_control);
0137 udelay(200);
0138
0139 spin_unlock_irqrestore(&chip->ad1843_lock, flags);
0140 return 0;
0141 }
0142
0143 static int sgio2audio_gain_info(struct snd_kcontrol *kcontrol,
0144 struct snd_ctl_elem_info *uinfo)
0145 {
0146 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
0147
0148 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0149 uinfo->count = 2;
0150 uinfo->value.integer.min = 0;
0151 uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843,
0152 (int)kcontrol->private_value);
0153 return 0;
0154 }
0155
0156 static int sgio2audio_gain_get(struct snd_kcontrol *kcontrol,
0157 struct snd_ctl_elem_value *ucontrol)
0158 {
0159 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
0160 int vol;
0161
0162 vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value);
0163
0164 ucontrol->value.integer.value[0] = (vol >> 8) & 0xFF;
0165 ucontrol->value.integer.value[1] = vol & 0xFF;
0166
0167 return 0;
0168 }
0169
0170 static int sgio2audio_gain_put(struct snd_kcontrol *kcontrol,
0171 struct snd_ctl_elem_value *ucontrol)
0172 {
0173 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
0174 int newvol, oldvol;
0175
0176 oldvol = ad1843_get_gain(&chip->ad1843, kcontrol->private_value);
0177 newvol = (ucontrol->value.integer.value[0] << 8) |
0178 ucontrol->value.integer.value[1];
0179
0180 newvol = ad1843_set_gain(&chip->ad1843, kcontrol->private_value,
0181 newvol);
0182
0183 return newvol != oldvol;
0184 }
0185
0186 static int sgio2audio_source_info(struct snd_kcontrol *kcontrol,
0187 struct snd_ctl_elem_info *uinfo)
0188 {
0189 static const char * const texts[3] = {
0190 "Cam Mic", "Mic", "Line"
0191 };
0192 return snd_ctl_enum_info(uinfo, 1, 3, texts);
0193 }
0194
0195 static int sgio2audio_source_get(struct snd_kcontrol *kcontrol,
0196 struct snd_ctl_elem_value *ucontrol)
0197 {
0198 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
0199
0200 ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843);
0201 return 0;
0202 }
0203
0204 static int sgio2audio_source_put(struct snd_kcontrol *kcontrol,
0205 struct snd_ctl_elem_value *ucontrol)
0206 {
0207 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
0208 int newsrc, oldsrc;
0209
0210 oldsrc = ad1843_get_recsrc(&chip->ad1843);
0211 newsrc = ad1843_set_recsrc(&chip->ad1843,
0212 ucontrol->value.enumerated.item[0]);
0213
0214 return newsrc != oldsrc;
0215 }
0216
0217
0218 static const struct snd_kcontrol_new sgio2audio_ctrl_pcm0 = {
0219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0220 .name = "PCM Playback Volume",
0221 .index = 0,
0222 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0223 .private_value = AD1843_GAIN_PCM_0,
0224 .info = sgio2audio_gain_info,
0225 .get = sgio2audio_gain_get,
0226 .put = sgio2audio_gain_put,
0227 };
0228
0229
0230 static const struct snd_kcontrol_new sgio2audio_ctrl_pcm1 = {
0231 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0232 .name = "PCM Playback Volume",
0233 .index = 1,
0234 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0235 .private_value = AD1843_GAIN_PCM_1,
0236 .info = sgio2audio_gain_info,
0237 .get = sgio2audio_gain_get,
0238 .put = sgio2audio_gain_put,
0239 };
0240
0241
0242 static const struct snd_kcontrol_new sgio2audio_ctrl_reclevel = {
0243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0244 .name = "Capture Volume",
0245 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0246 .private_value = AD1843_GAIN_RECLEV,
0247 .info = sgio2audio_gain_info,
0248 .get = sgio2audio_gain_get,
0249 .put = sgio2audio_gain_put,
0250 };
0251
0252
0253 static const struct snd_kcontrol_new sgio2audio_ctrl_recsource = {
0254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0255 .name = "Capture Source",
0256 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0257 .info = sgio2audio_source_info,
0258 .get = sgio2audio_source_get,
0259 .put = sgio2audio_source_put,
0260 };
0261
0262
0263 static const struct snd_kcontrol_new sgio2audio_ctrl_line = {
0264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0265 .name = "Line Playback Volume",
0266 .index = 0,
0267 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0268 .private_value = AD1843_GAIN_LINE,
0269 .info = sgio2audio_gain_info,
0270 .get = sgio2audio_gain_get,
0271 .put = sgio2audio_gain_put,
0272 };
0273
0274
0275 static const struct snd_kcontrol_new sgio2audio_ctrl_cd = {
0276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0277 .name = "Line Playback Volume",
0278 .index = 1,
0279 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0280 .private_value = AD1843_GAIN_LINE_2,
0281 .info = sgio2audio_gain_info,
0282 .get = sgio2audio_gain_get,
0283 .put = sgio2audio_gain_put,
0284 };
0285
0286
0287 static const struct snd_kcontrol_new sgio2audio_ctrl_mic = {
0288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0289 .name = "Mic Playback Volume",
0290 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0291 .private_value = AD1843_GAIN_MIC,
0292 .info = sgio2audio_gain_info,
0293 .get = sgio2audio_gain_get,
0294 .put = sgio2audio_gain_put,
0295 };
0296
0297
0298 static int snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip)
0299 {
0300 int err;
0301
0302 err = snd_ctl_add(chip->card,
0303 snd_ctl_new1(&sgio2audio_ctrl_pcm0, chip));
0304 if (err < 0)
0305 return err;
0306
0307 err = snd_ctl_add(chip->card,
0308 snd_ctl_new1(&sgio2audio_ctrl_pcm1, chip));
0309 if (err < 0)
0310 return err;
0311
0312 err = snd_ctl_add(chip->card,
0313 snd_ctl_new1(&sgio2audio_ctrl_reclevel, chip));
0314 if (err < 0)
0315 return err;
0316
0317 err = snd_ctl_add(chip->card,
0318 snd_ctl_new1(&sgio2audio_ctrl_recsource, chip));
0319 if (err < 0)
0320 return err;
0321 err = snd_ctl_add(chip->card,
0322 snd_ctl_new1(&sgio2audio_ctrl_line, chip));
0323 if (err < 0)
0324 return err;
0325
0326 err = snd_ctl_add(chip->card,
0327 snd_ctl_new1(&sgio2audio_ctrl_cd, chip));
0328 if (err < 0)
0329 return err;
0330
0331 err = snd_ctl_add(chip->card,
0332 snd_ctl_new1(&sgio2audio_ctrl_mic, chip));
0333 if (err < 0)
0334 return err;
0335
0336 return 0;
0337 }
0338
0339
0340
0341
0342
0343 static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip,
0344 unsigned int ch, unsigned int count)
0345 {
0346 int ret;
0347 unsigned long src_base, src_pos, dst_mask;
0348 unsigned char *dst_base;
0349 int dst_pos;
0350 u64 *src;
0351 s16 *dst;
0352 u64 x;
0353 unsigned long flags;
0354 struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
0355
0356 spin_lock_irqsave(&chip->channel[ch].lock, flags);
0357
0358 src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT);
0359 src_pos = readq(&mace->perif.audio.chan[ch].read_ptr);
0360 dst_base = runtime->dma_area;
0361 dst_pos = chip->channel[ch].pos;
0362 dst_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
0363
0364
0365 chip->channel[ch].size += (count >> 3);
0366 ret = chip->channel[ch].size >= runtime->period_size;
0367 chip->channel[ch].size %= runtime->period_size;
0368
0369 while (count) {
0370 src = (u64 *)(src_base + src_pos);
0371 dst = (s16 *)(dst_base + dst_pos);
0372
0373 x = *src;
0374 dst[0] = (x >> CHANNEL_LEFT_SHIFT) & 0xffff;
0375 dst[1] = (x >> CHANNEL_RIGHT_SHIFT) & 0xffff;
0376
0377 src_pos = (src_pos + sizeof(u64)) & CHANNEL_RING_MASK;
0378 dst_pos = (dst_pos + 2 * sizeof(s16)) & dst_mask;
0379 count -= sizeof(u64);
0380 }
0381
0382 writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr);
0383 chip->channel[ch].pos = dst_pos;
0384
0385 spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
0386 return ret;
0387 }
0388
0389
0390
0391 static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip,
0392 unsigned int ch, unsigned int count)
0393 {
0394 int ret;
0395 s64 l, r;
0396 unsigned long dst_base, dst_pos, src_mask;
0397 unsigned char *src_base;
0398 int src_pos;
0399 u64 *dst;
0400 s16 *src;
0401 unsigned long flags;
0402 struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime;
0403
0404 spin_lock_irqsave(&chip->channel[ch].lock, flags);
0405
0406 dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT);
0407 dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr);
0408 src_base = runtime->dma_area;
0409 src_pos = chip->channel[ch].pos;
0410 src_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1;
0411
0412
0413 chip->channel[ch].size += (count >> 3);
0414 ret = chip->channel[ch].size >= runtime->period_size;
0415 chip->channel[ch].size %= runtime->period_size;
0416
0417 while (count) {
0418 src = (s16 *)(src_base + src_pos);
0419 dst = (u64 *)(dst_base + dst_pos);
0420
0421 l = src[0];
0422 r = src[1];
0423
0424 *dst = ((l & 0x00ffffff) << CHANNEL_LEFT_SHIFT) |
0425 ((r & 0x00ffffff) << CHANNEL_RIGHT_SHIFT);
0426
0427 dst_pos = (dst_pos + sizeof(u64)) & CHANNEL_RING_MASK;
0428 src_pos = (src_pos + 2 * sizeof(s16)) & src_mask;
0429 count -= sizeof(u64);
0430 }
0431
0432 writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr);
0433 chip->channel[ch].pos = src_pos;
0434
0435 spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
0436 return ret;
0437 }
0438
0439 static int snd_sgio2audio_dma_start(struct snd_pcm_substream *substream)
0440 {
0441 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
0442 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
0443 int ch = chan->idx;
0444
0445
0446 writeq(CHANNEL_CONTROL_RESET, &mace->perif.audio.chan[ch].control);
0447 udelay(10);
0448 writeq(0, &mace->perif.audio.chan[ch].control);
0449
0450 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0451
0452 snd_sgio2audio_dma_push_frag(chip, ch, CHANNEL_RING_SIZE - 32);
0453 }
0454
0455 writeq(CHANNEL_DMA_ENABLE | CHANNEL_INT_THRESHOLD_50,
0456 &mace->perif.audio.chan[ch].control);
0457 return 0;
0458 }
0459
0460 static int snd_sgio2audio_dma_stop(struct snd_pcm_substream *substream)
0461 {
0462 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
0463
0464 writeq(0, &mace->perif.audio.chan[chan->idx].control);
0465 return 0;
0466 }
0467
0468 static irqreturn_t snd_sgio2audio_dma_in_isr(int irq, void *dev_id)
0469 {
0470 struct snd_sgio2audio_chan *chan = dev_id;
0471 struct snd_pcm_substream *substream;
0472 struct snd_sgio2audio *chip;
0473 int count, ch;
0474
0475 substream = chan->substream;
0476 chip = snd_pcm_substream_chip(substream);
0477 ch = chan->idx;
0478
0479
0480 count = CHANNEL_RING_SIZE -
0481 readq(&mace->perif.audio.chan[ch].depth) - 32;
0482 if (snd_sgio2audio_dma_pull_frag(chip, ch, count))
0483 snd_pcm_period_elapsed(substream);
0484
0485 return IRQ_HANDLED;
0486 }
0487
0488 static irqreturn_t snd_sgio2audio_dma_out_isr(int irq, void *dev_id)
0489 {
0490 struct snd_sgio2audio_chan *chan = dev_id;
0491 struct snd_pcm_substream *substream;
0492 struct snd_sgio2audio *chip;
0493 int count, ch;
0494
0495 substream = chan->substream;
0496 chip = snd_pcm_substream_chip(substream);
0497 ch = chan->idx;
0498
0499 count = CHANNEL_RING_SIZE -
0500 readq(&mace->perif.audio.chan[ch].depth) - 32;
0501 if (snd_sgio2audio_dma_push_frag(chip, ch, count))
0502 snd_pcm_period_elapsed(substream);
0503
0504 return IRQ_HANDLED;
0505 }
0506
0507 static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id)
0508 {
0509 struct snd_sgio2audio_chan *chan = dev_id;
0510 struct snd_pcm_substream *substream;
0511
0512 substream = chan->substream;
0513 snd_sgio2audio_dma_stop(substream);
0514 snd_sgio2audio_dma_start(substream);
0515 return IRQ_HANDLED;
0516 }
0517
0518
0519
0520 static const struct snd_pcm_hardware snd_sgio2audio_pcm_hw = {
0521 .info = (SNDRV_PCM_INFO_MMAP |
0522 SNDRV_PCM_INFO_MMAP_VALID |
0523 SNDRV_PCM_INFO_INTERLEAVED |
0524 SNDRV_PCM_INFO_BLOCK_TRANSFER),
0525 .formats = SNDRV_PCM_FMTBIT_S16_BE,
0526 .rates = SNDRV_PCM_RATE_8000_48000,
0527 .rate_min = 8000,
0528 .rate_max = 48000,
0529 .channels_min = 2,
0530 .channels_max = 2,
0531 .buffer_bytes_max = 65536,
0532 .period_bytes_min = 32768,
0533 .period_bytes_max = 65536,
0534 .periods_min = 1,
0535 .periods_max = 1024,
0536 };
0537
0538
0539 static int snd_sgio2audio_playback1_open(struct snd_pcm_substream *substream)
0540 {
0541 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
0542 struct snd_pcm_runtime *runtime = substream->runtime;
0543
0544 runtime->hw = snd_sgio2audio_pcm_hw;
0545 runtime->private_data = &chip->channel[1];
0546 return 0;
0547 }
0548
0549 static int snd_sgio2audio_playback2_open(struct snd_pcm_substream *substream)
0550 {
0551 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
0552 struct snd_pcm_runtime *runtime = substream->runtime;
0553
0554 runtime->hw = snd_sgio2audio_pcm_hw;
0555 runtime->private_data = &chip->channel[2];
0556 return 0;
0557 }
0558
0559
0560 static int snd_sgio2audio_capture_open(struct snd_pcm_substream *substream)
0561 {
0562 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
0563 struct snd_pcm_runtime *runtime = substream->runtime;
0564
0565 runtime->hw = snd_sgio2audio_pcm_hw;
0566 runtime->private_data = &chip->channel[0];
0567 return 0;
0568 }
0569
0570
0571 static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
0572 {
0573 struct snd_pcm_runtime *runtime = substream->runtime;
0574
0575 runtime->private_data = NULL;
0576 return 0;
0577 }
0578
0579
0580 static int snd_sgio2audio_pcm_prepare(struct snd_pcm_substream *substream)
0581 {
0582 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
0583 struct snd_pcm_runtime *runtime = substream->runtime;
0584 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
0585 int ch = chan->idx;
0586 unsigned long flags;
0587
0588 spin_lock_irqsave(&chip->channel[ch].lock, flags);
0589
0590
0591 chip->channel[ch].pos = 0;
0592 chip->channel[ch].size = 0;
0593 chip->channel[ch].substream = substream;
0594
0595
0596
0597 switch (substream->stream) {
0598 case SNDRV_PCM_STREAM_PLAYBACK:
0599 ad1843_setup_dac(&chip->ad1843,
0600 ch - 1,
0601 runtime->rate,
0602 SNDRV_PCM_FORMAT_S16_LE,
0603 runtime->channels);
0604 break;
0605 case SNDRV_PCM_STREAM_CAPTURE:
0606 ad1843_setup_adc(&chip->ad1843,
0607 runtime->rate,
0608 SNDRV_PCM_FORMAT_S16_LE,
0609 runtime->channels);
0610 break;
0611 }
0612 spin_unlock_irqrestore(&chip->channel[ch].lock, flags);
0613 return 0;
0614 }
0615
0616
0617 static int snd_sgio2audio_pcm_trigger(struct snd_pcm_substream *substream,
0618 int cmd)
0619 {
0620 switch (cmd) {
0621 case SNDRV_PCM_TRIGGER_START:
0622
0623 snd_sgio2audio_dma_start(substream);
0624 break;
0625 case SNDRV_PCM_TRIGGER_STOP:
0626
0627 snd_sgio2audio_dma_stop(substream);
0628 break;
0629 default:
0630 return -EINVAL;
0631 }
0632 return 0;
0633 }
0634
0635
0636 static snd_pcm_uframes_t
0637 snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
0638 {
0639 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream);
0640 struct snd_sgio2audio_chan *chan = substream->runtime->private_data;
0641
0642
0643 return bytes_to_frames(substream->runtime,
0644 chip->channel[chan->idx].pos);
0645 }
0646
0647
0648 static const struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
0649 .open = snd_sgio2audio_playback1_open,
0650 .close = snd_sgio2audio_pcm_close,
0651 .prepare = snd_sgio2audio_pcm_prepare,
0652 .trigger = snd_sgio2audio_pcm_trigger,
0653 .pointer = snd_sgio2audio_pcm_pointer,
0654 };
0655
0656 static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
0657 .open = snd_sgio2audio_playback2_open,
0658 .close = snd_sgio2audio_pcm_close,
0659 .prepare = snd_sgio2audio_pcm_prepare,
0660 .trigger = snd_sgio2audio_pcm_trigger,
0661 .pointer = snd_sgio2audio_pcm_pointer,
0662 };
0663
0664 static const struct snd_pcm_ops snd_sgio2audio_capture_ops = {
0665 .open = snd_sgio2audio_capture_open,
0666 .close = snd_sgio2audio_pcm_close,
0667 .prepare = snd_sgio2audio_pcm_prepare,
0668 .trigger = snd_sgio2audio_pcm_trigger,
0669 .pointer = snd_sgio2audio_pcm_pointer,
0670 };
0671
0672
0673
0674
0675
0676
0677 static int snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip)
0678 {
0679 struct snd_pcm *pcm;
0680 int err;
0681
0682
0683 err = snd_pcm_new(chip->card, "SGI O2 Audio", 0, 1, 1, &pcm);
0684 if (err < 0)
0685 return err;
0686
0687 pcm->private_data = chip;
0688 strcpy(pcm->name, "SGI O2 DAC1");
0689
0690
0691 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
0692 &snd_sgio2audio_playback1_ops);
0693 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
0694 &snd_sgio2audio_capture_ops);
0695 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
0696
0697
0698 err = snd_pcm_new(chip->card, "SGI O2 Audio", 1, 1, 0, &pcm);
0699 if (err < 0)
0700 return err;
0701
0702 pcm->private_data = chip;
0703 strcpy(pcm->name, "SGI O2 DAC2");
0704
0705
0706 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
0707 &snd_sgio2audio_playback2_ops);
0708 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
0709
0710 return 0;
0711 }
0712
0713 static struct {
0714 int idx;
0715 int irq;
0716 irqreturn_t (*isr)(int, void *);
0717 const char *desc;
0718 } snd_sgio2_isr_table[] = {
0719 {
0720 .idx = 0,
0721 .irq = MACEISA_AUDIO1_DMAT_IRQ,
0722 .isr = snd_sgio2audio_dma_in_isr,
0723 .desc = "Capture DMA Channel 0"
0724 }, {
0725 .idx = 0,
0726 .irq = MACEISA_AUDIO1_OF_IRQ,
0727 .isr = snd_sgio2audio_error_isr,
0728 .desc = "Capture Overflow"
0729 }, {
0730 .idx = 1,
0731 .irq = MACEISA_AUDIO2_DMAT_IRQ,
0732 .isr = snd_sgio2audio_dma_out_isr,
0733 .desc = "Playback DMA Channel 1"
0734 }, {
0735 .idx = 1,
0736 .irq = MACEISA_AUDIO2_MERR_IRQ,
0737 .isr = snd_sgio2audio_error_isr,
0738 .desc = "Memory Error Channel 1"
0739 }, {
0740 .idx = 2,
0741 .irq = MACEISA_AUDIO3_DMAT_IRQ,
0742 .isr = snd_sgio2audio_dma_out_isr,
0743 .desc = "Playback DMA Channel 2"
0744 }, {
0745 .idx = 2,
0746 .irq = MACEISA_AUDIO3_MERR_IRQ,
0747 .isr = snd_sgio2audio_error_isr,
0748 .desc = "Memory Error Channel 2"
0749 }
0750 };
0751
0752
0753
0754 static int snd_sgio2audio_free(struct snd_sgio2audio *chip)
0755 {
0756 int i;
0757
0758
0759 writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
0760 udelay(1);
0761 writeq(0, &mace->perif.audio.control);
0762
0763
0764 for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++)
0765 free_irq(snd_sgio2_isr_table[i].irq,
0766 &chip->channel[snd_sgio2_isr_table[i].idx]);
0767
0768 dma_free_coherent(chip->card->dev, MACEISA_RINGBUFFERS_SIZE,
0769 chip->ring_base, chip->ring_base_dma);
0770
0771
0772 kfree(chip);
0773 return 0;
0774 }
0775
0776 static int snd_sgio2audio_dev_free(struct snd_device *device)
0777 {
0778 struct snd_sgio2audio *chip = device->device_data;
0779
0780 return snd_sgio2audio_free(chip);
0781 }
0782
0783 static const struct snd_device_ops ops = {
0784 .dev_free = snd_sgio2audio_dev_free,
0785 };
0786
0787 static int snd_sgio2audio_create(struct snd_card *card,
0788 struct snd_sgio2audio **rchip)
0789 {
0790 struct snd_sgio2audio *chip;
0791 int i, err;
0792
0793 *rchip = NULL;
0794
0795
0796
0797 if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT))
0798 return -ENOENT;
0799
0800 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
0801 if (chip == NULL)
0802 return -ENOMEM;
0803
0804 chip->card = card;
0805
0806 chip->ring_base = dma_alloc_coherent(card->dev,
0807 MACEISA_RINGBUFFERS_SIZE,
0808 &chip->ring_base_dma, GFP_KERNEL);
0809 if (chip->ring_base == NULL) {
0810 printk(KERN_ERR
0811 "sgio2audio: could not allocate ring buffers\n");
0812 kfree(chip);
0813 return -ENOMEM;
0814 }
0815
0816 spin_lock_init(&chip->ad1843_lock);
0817
0818
0819 for (i = 0; i < 3; i++) {
0820 spin_lock_init(&chip->channel[i].lock);
0821 chip->channel[i].idx = i;
0822 }
0823
0824
0825 for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) {
0826 if (request_irq(snd_sgio2_isr_table[i].irq,
0827 snd_sgio2_isr_table[i].isr,
0828 0,
0829 snd_sgio2_isr_table[i].desc,
0830 &chip->channel[snd_sgio2_isr_table[i].idx])) {
0831 snd_sgio2audio_free(chip);
0832 printk(KERN_ERR "sgio2audio: cannot allocate irq %d\n",
0833 snd_sgio2_isr_table[i].irq);
0834 return -EBUSY;
0835 }
0836 }
0837
0838
0839 writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control);
0840 udelay(1);
0841 writeq(0, &mace->perif.audio.control);
0842 msleep_interruptible(1);
0843
0844
0845 writeq(chip->ring_base_dma, &mace->perif.ctrl.ringbase);
0846
0847
0848 chip->ad1843.read = read_ad1843_reg;
0849 chip->ad1843.write = write_ad1843_reg;
0850 chip->ad1843.chip = chip;
0851
0852
0853 err = ad1843_init(&chip->ad1843);
0854 if (err < 0) {
0855 snd_sgio2audio_free(chip);
0856 return err;
0857 }
0858
0859 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
0860 if (err < 0) {
0861 snd_sgio2audio_free(chip);
0862 return err;
0863 }
0864 *rchip = chip;
0865 return 0;
0866 }
0867
0868 static int snd_sgio2audio_probe(struct platform_device *pdev)
0869 {
0870 struct snd_card *card;
0871 struct snd_sgio2audio *chip;
0872 int err;
0873
0874 err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
0875 if (err < 0)
0876 return err;
0877
0878 err = snd_sgio2audio_create(card, &chip);
0879 if (err < 0) {
0880 snd_card_free(card);
0881 return err;
0882 }
0883
0884 err = snd_sgio2audio_new_pcm(chip);
0885 if (err < 0) {
0886 snd_card_free(card);
0887 return err;
0888 }
0889 err = snd_sgio2audio_new_mixer(chip);
0890 if (err < 0) {
0891 snd_card_free(card);
0892 return err;
0893 }
0894
0895 strcpy(card->driver, "SGI O2 Audio");
0896 strcpy(card->shortname, "SGI O2 Audio");
0897 sprintf(card->longname, "%s irq %i-%i",
0898 card->shortname,
0899 MACEISA_AUDIO1_DMAT_IRQ,
0900 MACEISA_AUDIO3_MERR_IRQ);
0901
0902 err = snd_card_register(card);
0903 if (err < 0) {
0904 snd_card_free(card);
0905 return err;
0906 }
0907 platform_set_drvdata(pdev, card);
0908 return 0;
0909 }
0910
0911 static int snd_sgio2audio_remove(struct platform_device *pdev)
0912 {
0913 struct snd_card *card = platform_get_drvdata(pdev);
0914
0915 snd_card_free(card);
0916 return 0;
0917 }
0918
0919 static struct platform_driver sgio2audio_driver = {
0920 .probe = snd_sgio2audio_probe,
0921 .remove = snd_sgio2audio_remove,
0922 .driver = {
0923 .name = "sgio2audio",
0924 }
0925 };
0926
0927 module_platform_driver(sgio2audio_driver);