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