Linux Audio

Check our new training course

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