1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56#include <linux/interrupt.h>
57#include <linux/delay.h>
58#include <linux/irq.h>
59#include <linux/io.h>
60#include <linux/dma-mapping.h>
61#include <linux/gfp.h>
62
63#include <sound/core.h>
64#include <sound/pcm.h>
65#include <sound/pcm_params.h>
66#include <sound/info.h>
67#include <sound/control.h>
68#include <sound/initval.h>
69
70#include <linux/of.h>
71#include <linux/of_device.h>
72#include <asm/atomic.h>
73
74MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
75MODULE_DESCRIPTION("Sun DBRI");
76MODULE_LICENSE("GPL");
77MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}");
78
79static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
80static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
81
82static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
83
84module_param_array(index, int, NULL, 0444);
85MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard.");
86module_param_array(id, charp, NULL, 0444);
87MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard.");
88module_param_array(enable, bool, NULL, 0444);
89MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
90
91#undef DBRI_DEBUG
92
93#define D_INT (1<<0)
94#define D_GEN (1<<1)
95#define D_CMD (1<<2)
96#define D_MM (1<<3)
97#define D_USR (1<<4)
98#define D_DESC (1<<5)
99
100static int dbri_debug;
101module_param(dbri_debug, int, 0644);
102MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
103
104#ifdef DBRI_DEBUG
105static char *cmds[] = {
106 "WAIT", "PAUSE", "JUMP", "IIQ", "REX", "SDP", "CDP", "DTS",
107 "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV"
108};
109
110#define dprintk(a, x...) if (dbri_debug & a) printk(KERN_DEBUG x)
111
112#else
113#define dprintk(a, x...) do { } while (0)
114
115#endif
116
117#define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \
118 (intr << 27) | \
119 value)
120
121
122
123
124
125struct cs4215 {
126 __u8 data[4];
127 __u8 ctrl[4];
128 __u8 onboard;
129 __u8 offset;
130 volatile __u32 status;
131 volatile __u32 version;
132 __u8 precision;
133 __u8 channels;
134};
135
136
137
138
139
140
141#define CS4215_CLB (1<<2)
142#define CS4215_OLB (1<<3)
143
144#define CS4215_MLB (1<<4)
145#define CS4215_RSRVD_1 (1<<5)
146
147
148#define CS4215_DFR_LINEAR16 0
149#define CS4215_DFR_ULAW 1
150#define CS4215_DFR_ALAW 2
151#define CS4215_DFR_LINEAR8 3
152#define CS4215_DFR_STEREO (1<<2)
153static struct {
154 unsigned short freq;
155 unsigned char xtal;
156 unsigned char csval;
157} CS4215_FREQ[] = {
158 { 8000, (1 << 4), (0 << 3) },
159 { 16000, (1 << 4), (1 << 3) },
160 { 27429, (1 << 4), (2 << 3) },
161 { 32000, (1 << 4), (3 << 3) },
162
163
164 { 48000, (1 << 4), (6 << 3) },
165 { 9600, (1 << 4), (7 << 3) },
166 { 5512, (2 << 4), (0 << 3) },
167 { 11025, (2 << 4), (1 << 3) },
168 { 18900, (2 << 4), (2 << 3) },
169 { 22050, (2 << 4), (3 << 3) },
170 { 37800, (2 << 4), (4 << 3) },
171 { 44100, (2 << 4), (5 << 3) },
172 { 33075, (2 << 4), (6 << 3) },
173 { 6615, (2 << 4), (7 << 3) },
174 { 0, 0, 0}
175};
176
177#define CS4215_HPF (1<<7)
178
179#define CS4215_12_MASK 0xfcbf
180
181
182#define CS4215_XEN (1<<0)
183#define CS4215_XCLK (1<<1)
184#define CS4215_BSEL_64 (0<<2)
185#define CS4215_BSEL_128 (1<<2)
186#define CS4215_BSEL_256 (2<<2)
187#define CS4215_MCK_MAST (0<<4)
188#define CS4215_MCK_XTL1 (1<<4)
189#define CS4215_MCK_XTL2 (2<<4)
190#define CS4215_MCK_CLK1 (3<<4)
191#define CS4215_MCK_CLK2 (4<<4)
192
193
194#define CS4215_DAD (1<<0)
195#define CS4215_ENL (1<<1)
196
197
198
199
200
201
202
203#define CS4215_VERSION_MASK 0xf
204
205
206
207
208
209
210
211
212
213#define CS4215_LO(v) v
214#define CS4215_LE (1<<6)
215#define CS4215_HE (1<<7)
216
217
218#define CS4215_RO(v) v
219#define CS4215_SE (1<<6)
220#define CS4215_ADI (1<<7)
221
222
223#define CS4215_LG(v) v
224#define CS4215_IS (1<<4)
225#define CS4215_OVR (1<<5)
226#define CS4215_PIO0 (1<<6)
227#define CS4215_PIO1 (1<<7)
228
229
230#define CS4215_RG(v) v
231#define CS4215_MA(v) (v<<4)
232
233
234
235
236
237
238#define REG0 0x00
239#define REG1 0x04
240#define REG2 0x08
241#define REG3 0x0c
242#define REG8 0x20
243#define REG9 0x24
244
245#define DBRI_NO_CMDS 64
246#define DBRI_INT_BLK 64
247#define DBRI_NO_DESCS 64
248#define DBRI_NO_PIPES 32
249#define DBRI_MAX_PIPE (DBRI_NO_PIPES - 1)
250
251#define DBRI_REC 0
252#define DBRI_PLAY 1
253#define DBRI_NO_STREAMS 2
254
255
256
257struct dbri_mem {
258 volatile __u32 word1;
259 __u32 ba;
260 __u32 nda;
261 volatile __u32 word4;
262};
263
264
265
266
267struct dbri_dma {
268 s32 cmd[DBRI_NO_CMDS];
269 volatile s32 intr[DBRI_INT_BLK];
270 struct dbri_mem desc[DBRI_NO_DESCS];
271};
272
273#define dbri_dma_off(member, elem) \
274 ((u32)(unsigned long) \
275 (&(((struct dbri_dma *)0)->member[elem])))
276
277enum in_or_out { PIPEinput, PIPEoutput };
278
279struct dbri_pipe {
280 u32 sdp;
281 int nextpipe;
282 int length;
283 int first_desc;
284 int desc;
285 volatile __u32 *recv_fixed_ptr;
286};
287
288
289struct dbri_streaminfo {
290 struct snd_pcm_substream *substream;
291 u32 dvma_buffer;
292 int size;
293 size_t offset;
294 int pipe;
295 int left_gain;
296 int right_gain;
297};
298
299
300struct snd_dbri {
301 int regs_size, irq;
302 struct platform_device *op;
303 spinlock_t lock;
304
305 struct dbri_dma *dma;
306 u32 dma_dvma;
307
308 void __iomem *regs;
309 int dbri_irqp;
310
311 struct dbri_pipe pipes[DBRI_NO_PIPES];
312 int next_desc[DBRI_NO_DESCS];
313 spinlock_t cmdlock;
314 s32 *cmdptr;
315
316 int chi_bpf;
317
318 struct cs4215 mm;
319
320 struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];
321};
322
323#define DBRI_MAX_VOLUME 63
324#define DBRI_MAX_GAIN 15
325
326
327#define D_P (1<<15)
328#define D_G (1<<14)
329#define D_S (1<<13)
330#define D_E (1<<12)
331#define D_X (1<<7)
332#define D_T (1<<6)
333#define D_N (1<<5)
334#define D_C (1<<4)
335#define D_F (1<<3)
336#define D_D (1<<2)
337#define D_H (1<<1)
338#define D_R (1<<0)
339
340
341#define D_LITTLE_END (1<<8)
342#define D_BIG_END (0<<8)
343#define D_MRR (1<<4)
344#define D_MLE (1<<3)
345#define D_LBG (1<<2)
346#define D_MBE (1<<1)
347#define D_IR (1<<0)
348
349
350#define D_ENPIO3 (1<<7)
351#define D_ENPIO2 (1<<6)
352#define D_ENPIO1 (1<<5)
353#define D_ENPIO0 (1<<4)
354#define D_ENPIO (0xf0)
355#define D_PIO3 (1<<3)
356#define D_PIO2 (1<<2)
357#define D_PIO1 (1<<1)
358#define D_PIO0 (1<<0)
359
360
361#define D_WAIT 0x0
362#define D_PAUSE 0x1
363#define D_JUMP 0x2
364#define D_IIQ 0x3
365#define D_REX 0x4
366#define D_SDP 0x5
367#define D_CDP 0x6
368#define D_DTS 0x7
369#define D_SSP 0x8
370#define D_CHI 0x9
371#define D_NT 0xa
372#define D_TE 0xb
373#define D_CDEC 0xc
374#define D_TEST 0xd
375#define D_CDM 0xe
376
377
378#define D_PIPE(v) ((v)<<0)
379
380
381
382#define D_SDP_2SAME (1<<18)
383#define D_SDP_CHANGE (2<<18)
384#define D_SDP_EVERY (3<<18)
385#define D_SDP_EOL (1<<17)
386#define D_SDP_IDLE (1<<16)
387
388
389#define D_SDP_MEM (0<<13)
390#define D_SDP_HDLC (2<<13)
391#define D_SDP_HDLC_D (3<<13)
392#define D_SDP_SER (4<<13)
393#define D_SDP_FIXED (6<<13)
394#define D_SDP_MODE(v) ((v)&(7<<13))
395
396#define D_SDP_TO_SER (1<<12)
397#define D_SDP_FROM_SER (0<<12)
398#define D_SDP_MSB (1<<11)
399#define D_SDP_LSB (0<<11)
400#define D_SDP_P (1<<10)
401#define D_SDP_A (1<<8)
402#define D_SDP_C (1<<7)
403
404
405#define D_DTS_VI (1<<17)
406#define D_DTS_VO (1<<16)
407#define D_DTS_INS (1<<15)
408#define D_DTS_DEL (0<<15)
409#define D_DTS_PRVIN(v) ((v)<<10)
410#define D_DTS_PRVOUT(v) ((v)<<5)
411
412
413#define D_TS_LEN(v) ((v)<<24)
414#define D_TS_CYCLE(v) ((v)<<14)
415#define D_TS_DI (1<<13)
416#define D_TS_1CHANNEL (0<<10)
417#define D_TS_MONITOR (2<<10)
418#define D_TS_NONCONTIG (3<<10)
419#define D_TS_ANCHOR (7<<10)
420#define D_TS_MON(v) ((v)<<5)
421#define D_TS_NEXT(v) ((v)<<0)
422
423
424#define D_CHI_CHICM(v) ((v)<<16)
425#define D_CHI_IR (1<<15)
426#define D_CHI_EN (1<<14)
427#define D_CHI_OD (1<<13)
428#define D_CHI_FE (1<<12)
429#define D_CHI_FD (1<<11)
430#define D_CHI_BPF(v) ((v)<<0)
431
432
433#define D_NT_FBIT (1<<17)
434#define D_NT_NBF (1<<16)
435#define D_NT_IRM_IMM (1<<15)
436#define D_NT_IRM_EN (1<<14)
437#define D_NT_ISNT (1<<13)
438#define D_NT_FT (1<<12)
439#define D_NT_EZ (1<<11)
440#define D_NT_IFA (1<<10)
441#define D_NT_ACT (1<<9)
442#define D_NT_MFE (1<<8)
443#define D_NT_RLB(v) ((v)<<5)
444#define D_NT_LLB(v) ((v)<<2)
445#define D_NT_FACT (1<<1)
446#define D_NT_ABV (1<<0)
447
448
449#define D_CDEC_CK(v) ((v)<<24)
450#define D_CDEC_FED(v) ((v)<<12)
451#define D_CDEC_RED(v) ((v)<<0)
452
453
454#define D_TEST_RAM(v) ((v)<<16)
455#define D_TEST_SIZE(v) ((v)<<11)
456#define D_TEST_ROMONOFF 0x5
457#define D_TEST_PROC 0x6
458#define D_TEST_SER 0x7
459#define D_TEST_RAMREAD 0x8
460#define D_TEST_RAMWRITE 0x9
461#define D_TEST_RAMBIST 0xa
462#define D_TEST_MCBIST 0xb
463#define D_TEST_DUMP 0xe
464
465
466#define D_CDM_THI (1 << 8)
467#define D_CDM_RHI (1 << 7)
468#define D_CDM_RCE (1 << 6)
469#define D_CDM_XCE (1 << 2)
470#define D_CDM_XEN (1 << 1)
471#define D_CDM_REN (1 << 0)
472
473
474#define D_INTR_BRDY 1
475#define D_INTR_MINT 2
476#define D_INTR_IBEG 3
477#define D_INTR_IEND 4
478#define D_INTR_EOL 5
479#define D_INTR_CMDI 6
480#define D_INTR_XCMP 8
481#define D_INTR_SBRI 9
482#define D_INTR_FXDT 10
483#define D_INTR_CHIL 11
484#define D_INTR_COLL 11
485#define D_INTR_DBYT 12
486#define D_INTR_RBYT 13
487#define D_INTR_LINT 14
488#define D_INTR_UNDR 15
489
490#define D_INTR_TE 32
491#define D_INTR_NT 34
492#define D_INTR_CHI 36
493#define D_INTR_CMD 38
494
495#define D_INTR_GETCHAN(v) (((v) >> 24) & 0x3f)
496#define D_INTR_GETCODE(v) (((v) >> 20) & 0xf)
497#define D_INTR_GETCMD(v) (((v) >> 16) & 0xf)
498#define D_INTR_GETVAL(v) ((v) & 0xffff)
499#define D_INTR_GETRVAL(v) ((v) & 0xfffff)
500
501#define D_P_0 0
502#define D_P_1 1
503#define D_P_2 2
504#define D_P_3 3
505#define D_P_4 4
506#define D_P_5 5
507#define D_P_6 6
508#define D_P_7 7
509#define D_P_8 8
510#define D_P_9 9
511#define D_P_10 10
512#define D_P_11 11
513#define D_P_12 12
514#define D_P_13 13
515#define D_P_14 14
516#define D_P_15 15
517#define D_P_16 16
518#define D_P_17 17
519#define D_P_18 18
520#define D_P_19 19
521#define D_P_20 20
522#define D_P_21 21
523#define D_P_22 22
524#define D_P_23 23
525#define D_P_24 24
526#define D_P_25 25
527#define D_P_26 26
528#define D_P_27 27
529#define D_P_28 28
530#define D_P_29 29
531#define D_P_30 30
532#define D_P_31 31
533
534
535#define DBRI_TD_F (1 << 31)
536#define DBRI_TD_D (1 << 30)
537#define DBRI_TD_CNT(v) ((v) << 16)
538#define DBRI_TD_B (1 << 15)
539#define DBRI_TD_M (1 << 14)
540#define DBRI_TD_I (1 << 13)
541#define DBRI_TD_FCNT(v) (v)
542#define DBRI_TD_UNR (1 << 3)
543#define DBRI_TD_ABT (1 << 2)
544#define DBRI_TD_TBC (1 << 0)
545#define DBRI_TD_STATUS(v) ((v) & 0xff)
546
547#define DBRI_TD_MAXCNT ((1 << 13) - 4)
548
549
550#define DBRI_RD_F (1 << 31)
551#define DBRI_RD_C (1 << 30)
552#define DBRI_RD_B (1 << 15)
553#define DBRI_RD_M (1 << 14)
554#define DBRI_RD_BCNT(v) (v)
555#define DBRI_RD_CRC (1 << 7)
556#define DBRI_RD_BBC (1 << 6)
557#define DBRI_RD_ABT (1 << 5)
558#define DBRI_RD_OVRN (1 << 3)
559#define DBRI_RD_STATUS(v) ((v) & 0xff)
560#define DBRI_RD_CNT(v) (((v) >> 16) & 0x1fff)
561
562
563
564#define DBRI_STREAMNO(substream) \
565 (substream->stream == \
566 SNDRV_PCM_STREAM_PLAYBACK ? DBRI_PLAY: DBRI_REC)
567
568
569#define DBRI_STREAM(dbri, substream) \
570 &dbri->stream_info[DBRI_STREAMNO(substream)]
571
572
573
574
575
576static __u32 reverse_bytes(__u32 b, int len)
577{
578 switch (len) {
579 case 32:
580 b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16);
581 case 16:
582 b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8);
583 case 8:
584 b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4);
585 case 4:
586 b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2);
587 case 2:
588 b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1);
589 case 1:
590 case 0:
591 break;
592 default:
593 printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n");
594 };
595
596 return b;
597}
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629#define MAXLOOPS 20
630
631
632
633static void dbri_cmdwait(struct snd_dbri *dbri)
634{
635 int maxloops = MAXLOOPS;
636 unsigned long flags;
637
638
639 spin_lock_irqsave(&dbri->lock, flags);
640 while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) {
641 spin_unlock_irqrestore(&dbri->lock, flags);
642 msleep_interruptible(1);
643 spin_lock_irqsave(&dbri->lock, flags);
644 }
645 spin_unlock_irqrestore(&dbri->lock, flags);
646
647 if (maxloops == 0)
648 printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
649 else
650 dprintk(D_CMD, "Chip completed command buffer (%d)\n",
651 MAXLOOPS - maxloops - 1);
652}
653
654
655
656
657static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len)
658{
659
660 len += 2;
661 spin_lock(&dbri->cmdlock);
662 if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2)
663 return dbri->cmdptr + 2;
664 else if (len < sbus_readl(dbri->regs + REG8) - dbri->dma_dvma)
665 return dbri->dma->cmd;
666 else
667 printk(KERN_ERR "DBRI: no space for commands.");
668
669 return NULL;
670}
671
672
673
674
675
676
677
678
679
680static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len)
681{
682 s32 tmp, addr;
683 static int wait_id = 0;
684
685 wait_id++;
686 wait_id &= 0xffff;
687 *(cmd) = DBRI_CMD(D_WAIT, 1, wait_id);
688 *(cmd+1) = DBRI_CMD(D_WAIT, 1, wait_id);
689
690
691 addr = dbri->dma_dvma + (cmd - len - dbri->dma->cmd) * sizeof(s32);
692 *(dbri->cmdptr+1) = addr;
693 *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0);
694
695#ifdef DBRI_DEBUG
696 if (cmd > dbri->cmdptr) {
697 s32 *ptr;
698
699 for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++)
700 dprintk(D_CMD, "cmd: %lx:%08x\n",
701 (unsigned long)ptr, *ptr);
702 } else {
703 s32 *ptr = dbri->cmdptr;
704
705 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
706 ptr++;
707 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
708 for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++)
709 dprintk(D_CMD, "cmd: %lx:%08x\n",
710 (unsigned long)ptr, *ptr);
711 }
712#endif
713
714
715 tmp = sbus_readl(dbri->regs + REG0);
716 tmp |= D_P;
717 sbus_writel(tmp, dbri->regs + REG0);
718
719 dbri->cmdptr = cmd;
720 spin_unlock(&dbri->cmdlock);
721}
722
723
724static void dbri_reset(struct snd_dbri *dbri)
725{
726 int i;
727 u32 tmp;
728
729 dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n",
730 sbus_readl(dbri->regs + REG0),
731 sbus_readl(dbri->regs + REG2),
732 sbus_readl(dbri->regs + REG8), sbus_readl(dbri->regs + REG9));
733
734 sbus_writel(D_R, dbri->regs + REG0);
735 for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++)
736 udelay(10);
737
738
739
740 tmp = sbus_readl(dbri->regs + REG0);
741 tmp |= D_G | D_E;
742 tmp &= ~D_S;
743 sbus_writel(tmp, dbri->regs + REG0);
744}
745
746
747static void __devinit dbri_initialize(struct snd_dbri *dbri)
748{
749 s32 *cmd;
750 u32 dma_addr;
751 unsigned long flags;
752 int n;
753
754 spin_lock_irqsave(&dbri->lock, flags);
755
756 dbri_reset(dbri);
757
758
759 for (n = 0; n < DBRI_NO_PIPES; n++)
760 dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
761
762 spin_lock_init(&dbri->cmdlock);
763
764
765
766 dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0);
767 dbri->dma->intr[0] = dma_addr;
768 dbri->dbri_irqp = 1;
769
770
771
772 spin_lock(&dbri->cmdlock);
773 cmd = dbri->cmdptr = dbri->dma->cmd;
774 *(cmd++) = DBRI_CMD(D_IIQ, 0, 0);
775 *(cmd++) = dma_addr;
776 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
777 dbri->cmdptr = cmd;
778 *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
779 *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
780 dma_addr = dbri->dma_dvma + dbri_dma_off(cmd, 0);
781 sbus_writel(dma_addr, dbri->regs + REG8);
782 spin_unlock(&dbri->cmdlock);
783
784 spin_unlock_irqrestore(&dbri->lock, flags);
785 dbri_cmdwait(dbri);
786}
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802static inline int pipe_active(struct snd_dbri *dbri, int pipe)
803{
804 return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1));
805}
806
807
808
809
810
811
812static void reset_pipe(struct snd_dbri *dbri, int pipe)
813{
814 int sdp;
815 int desc;
816 s32 *cmd;
817
818 if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
819 printk(KERN_ERR "DBRI: reset_pipe called with "
820 "illegal pipe number\n");
821 return;
822 }
823
824 sdp = dbri->pipes[pipe].sdp;
825 if (sdp == 0) {
826 printk(KERN_ERR "DBRI: reset_pipe called "
827 "on uninitialized pipe\n");
828 return;
829 }
830
831 cmd = dbri_cmdlock(dbri, 3);
832 *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P);
833 *(cmd++) = 0;
834 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
835 dbri_cmdsend(dbri, cmd, 3);
836
837 desc = dbri->pipes[pipe].first_desc;
838 if (desc >= 0)
839 do {
840 dbri->dma->desc[desc].ba = 0;
841 dbri->dma->desc[desc].nda = 0;
842 desc = dbri->next_desc[desc];
843 } while (desc != -1 && desc != dbri->pipes[pipe].first_desc);
844
845 dbri->pipes[pipe].desc = -1;
846 dbri->pipes[pipe].first_desc = -1;
847}
848
849
850
851
852static void setup_pipe(struct snd_dbri *dbri, int pipe, int sdp)
853{
854 if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
855 printk(KERN_ERR "DBRI: setup_pipe called "
856 "with illegal pipe number\n");
857 return;
858 }
859
860 if ((sdp & 0xf800) != sdp) {
861 printk(KERN_ERR "DBRI: setup_pipe called "
862 "with strange SDP value\n");
863
864 }
865
866
867
868
869 if (D_SDP_MODE(sdp) == D_SDP_FIXED && !(sdp & D_SDP_TO_SER))
870 sdp |= D_SDP_CHANGE;
871
872 sdp |= D_PIPE(pipe);
873 dbri->pipes[pipe].sdp = sdp;
874 dbri->pipes[pipe].desc = -1;
875 dbri->pipes[pipe].first_desc = -1;
876
877 reset_pipe(dbri, pipe);
878}
879
880
881
882
883static void link_time_slot(struct snd_dbri *dbri, int pipe,
884 int prevpipe, int nextpipe,
885 int length, int cycle)
886{
887 s32 *cmd;
888 int val;
889
890 if (pipe < 0 || pipe > DBRI_MAX_PIPE
891 || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
892 || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
893 printk(KERN_ERR
894 "DBRI: link_time_slot called with illegal pipe number\n");
895 return;
896 }
897
898 if (dbri->pipes[pipe].sdp == 0
899 || dbri->pipes[prevpipe].sdp == 0
900 || dbri->pipes[nextpipe].sdp == 0) {
901 printk(KERN_ERR "DBRI: link_time_slot called "
902 "on uninitialized pipe\n");
903 return;
904 }
905
906 dbri->pipes[prevpipe].nextpipe = pipe;
907 dbri->pipes[pipe].nextpipe = nextpipe;
908 dbri->pipes[pipe].length = length;
909
910 cmd = dbri_cmdlock(dbri, 4);
911
912 if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
913
914
915
916
917
918 if (prevpipe == 16 && cycle == 0)
919 cycle = dbri->chi_bpf;
920
921 val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe;
922 *(cmd++) = DBRI_CMD(D_DTS, 0, val);
923 *(cmd++) = 0;
924 *(cmd++) =
925 D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
926 } else {
927 val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe;
928 *(cmd++) = DBRI_CMD(D_DTS, 0, val);
929 *(cmd++) =
930 D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
931 *(cmd++) = 0;
932 }
933 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
934
935 dbri_cmdsend(dbri, cmd, 4);
936}
937
938#if 0
939
940
941
942static void unlink_time_slot(struct snd_dbri *dbri, int pipe,
943 enum in_or_out direction, int prevpipe,
944 int nextpipe)
945{
946 s32 *cmd;
947 int val;
948
949 if (pipe < 0 || pipe > DBRI_MAX_PIPE
950 || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
951 || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
952 printk(KERN_ERR
953 "DBRI: unlink_time_slot called with illegal pipe number\n");
954 return;
955 }
956
957 cmd = dbri_cmdlock(dbri, 4);
958
959 if (direction == PIPEinput) {
960 val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe;
961 *(cmd++) = DBRI_CMD(D_DTS, 0, val);
962 *(cmd++) = D_TS_NEXT(nextpipe);
963 *(cmd++) = 0;
964 } else {
965 val = D_DTS_VO | D_DTS_DEL | D_DTS_PRVOUT(prevpipe) | pipe;
966 *(cmd++) = DBRI_CMD(D_DTS, 0, val);
967 *(cmd++) = 0;
968 *(cmd++) = D_TS_NEXT(nextpipe);
969 }
970 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
971
972 dbri_cmdsend(dbri, cmd, 4);
973}
974#endif
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992static void xmit_fixed(struct snd_dbri *dbri, int pipe, unsigned int data)
993{
994 s32 *cmd;
995 unsigned long flags;
996
997 if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
998 printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n");
999 return;
1000 }
1001
1002 if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) {
1003 printk(KERN_ERR "DBRI: xmit_fixed: "
1004 "Uninitialized pipe %d\n", pipe);
1005 return;
1006 }
1007
1008 if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
1009 printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
1010 return;
1011 }
1012
1013 if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) {
1014 printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n",
1015 pipe);
1016 return;
1017 }
1018
1019
1020
1021 if (dbri->pipes[pipe].sdp & D_SDP_MSB)
1022 data = reverse_bytes(data, dbri->pipes[pipe].length);
1023
1024 cmd = dbri_cmdlock(dbri, 3);
1025
1026 *(cmd++) = DBRI_CMD(D_SSP, 0, pipe);
1027 *(cmd++) = data;
1028 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
1029
1030 spin_lock_irqsave(&dbri->lock, flags);
1031 dbri_cmdsend(dbri, cmd, 3);
1032 spin_unlock_irqrestore(&dbri->lock, flags);
1033 dbri_cmdwait(dbri);
1034
1035}
1036
1037static void recv_fixed(struct snd_dbri *dbri, int pipe, volatile __u32 *ptr)
1038{
1039 if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
1040 printk(KERN_ERR "DBRI: recv_fixed called with "
1041 "illegal pipe number\n");
1042 return;
1043 }
1044
1045 if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
1046 printk(KERN_ERR "DBRI: recv_fixed called on "
1047 "non-fixed pipe %d\n", pipe);
1048 return;
1049 }
1050
1051 if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
1052 printk(KERN_ERR "DBRI: recv_fixed called on "
1053 "transmit pipe %d\n", pipe);
1054 return;
1055 }
1056
1057 dbri->pipes[pipe].recv_fixed_ptr = ptr;
1058}
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
1077{
1078 struct dbri_streaminfo *info = &dbri->stream_info[streamno];
1079 __u32 dvma_buffer;
1080 int desc;
1081 int len;
1082 int first_desc = -1;
1083 int last_desc = -1;
1084
1085 if (info->pipe < 0 || info->pipe > 15) {
1086 printk(KERN_ERR "DBRI: setup_descs: Illegal pipe number\n");
1087 return -2;
1088 }
1089
1090 if (dbri->pipes[info->pipe].sdp == 0) {
1091 printk(KERN_ERR "DBRI: setup_descs: Uninitialized pipe %d\n",
1092 info->pipe);
1093 return -2;
1094 }
1095
1096 dvma_buffer = info->dvma_buffer;
1097 len = info->size;
1098
1099 if (streamno == DBRI_PLAY) {
1100 if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) {
1101 printk(KERN_ERR "DBRI: setup_descs: "
1102 "Called on receive pipe %d\n", info->pipe);
1103 return -2;
1104 }
1105 } else {
1106 if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) {
1107 printk(KERN_ERR
1108 "DBRI: setup_descs: Called on transmit pipe %d\n",
1109 info->pipe);
1110 return -2;
1111 }
1112
1113
1114
1115 if (pipe_active(dbri, info->pipe)) {
1116 printk(KERN_ERR "DBRI: recv_on_pipe: "
1117 "Called on active pipe %d\n", info->pipe);
1118 return -2;
1119 }
1120
1121
1122 len &= ~3;
1123 }
1124
1125
1126 desc = dbri->pipes[info->pipe].first_desc;
1127 if (desc >= 0)
1128 do {
1129 dbri->dma->desc[desc].ba = 0;
1130 dbri->dma->desc[desc].nda = 0;
1131 desc = dbri->next_desc[desc];
1132 } while (desc != -1 &&
1133 desc != dbri->pipes[info->pipe].first_desc);
1134
1135 dbri->pipes[info->pipe].desc = -1;
1136 dbri->pipes[info->pipe].first_desc = -1;
1137
1138 desc = 0;
1139 while (len > 0) {
1140 int mylen;
1141
1142 for (; desc < DBRI_NO_DESCS; desc++) {
1143 if (!dbri->dma->desc[desc].ba)
1144 break;
1145 }
1146
1147 if (desc == DBRI_NO_DESCS) {
1148 printk(KERN_ERR "DBRI: setup_descs: No descriptors\n");
1149 return -1;
1150 }
1151
1152 if (len > DBRI_TD_MAXCNT)
1153 mylen = DBRI_TD_MAXCNT;
1154 else
1155 mylen = len;
1156
1157 if (mylen > period)
1158 mylen = period;
1159
1160 dbri->next_desc[desc] = -1;
1161 dbri->dma->desc[desc].ba = dvma_buffer;
1162 dbri->dma->desc[desc].nda = 0;
1163
1164 if (streamno == DBRI_PLAY) {
1165 dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen);
1166 dbri->dma->desc[desc].word4 = 0;
1167 dbri->dma->desc[desc].word1 |= DBRI_TD_F | DBRI_TD_B;
1168 } else {
1169 dbri->dma->desc[desc].word1 = 0;
1170 dbri->dma->desc[desc].word4 =
1171 DBRI_RD_B | DBRI_RD_BCNT(mylen);
1172 }
1173
1174 if (first_desc == -1)
1175 first_desc = desc;
1176 else {
1177 dbri->next_desc[last_desc] = desc;
1178 dbri->dma->desc[last_desc].nda =
1179 dbri->dma_dvma + dbri_dma_off(desc, desc);
1180 }
1181
1182 last_desc = desc;
1183 dvma_buffer += mylen;
1184 len -= mylen;
1185 }
1186
1187 if (first_desc == -1 || last_desc == -1) {
1188 printk(KERN_ERR "DBRI: setup_descs: "
1189 " Not enough descriptors available\n");
1190 return -1;
1191 }
1192
1193 dbri->dma->desc[last_desc].nda =
1194 dbri->dma_dvma + dbri_dma_off(desc, first_desc);
1195 dbri->next_desc[last_desc] = first_desc;
1196 dbri->pipes[info->pipe].first_desc = first_desc;
1197 dbri->pipes[info->pipe].desc = first_desc;
1198
1199#ifdef DBRI_DEBUG
1200 for (desc = first_desc; desc != -1;) {
1201 dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n",
1202 desc,
1203 dbri->dma->desc[desc].word1,
1204 dbri->dma->desc[desc].ba,
1205 dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4);
1206 desc = dbri->next_desc[desc];
1207 if (desc == first_desc)
1208 break;
1209 }
1210#endif
1211 return 0;
1212}
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225enum master_or_slave { CHImaster, CHIslave };
1226
1227
1228
1229
1230static void reset_chi(struct snd_dbri *dbri,
1231 enum master_or_slave master_or_slave,
1232 int bits_per_frame)
1233{
1234 s32 *cmd;
1235 int val;
1236
1237
1238
1239 cmd = dbri_cmdlock(dbri, 4);
1240 val = D_DTS_VO | D_DTS_VI | D_DTS_INS
1241 | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16);
1242 *(cmd++) = DBRI_CMD(D_DTS, 0, val);
1243 *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
1244 *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
1245 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
1246 dbri_cmdsend(dbri, cmd, 4);
1247
1248 dbri->pipes[16].sdp = 1;
1249 dbri->pipes[16].nextpipe = 16;
1250
1251 cmd = dbri_cmdlock(dbri, 4);
1252
1253 if (master_or_slave == CHIslave) {
1254
1255
1256
1257
1258
1259
1260 *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(0));
1261 } else {
1262
1263
1264
1265
1266
1267
1268 int clockrate = bits_per_frame * 8;
1269 int divisor = 12288 / clockrate;
1270
1271 if (divisor > 255 || divisor * clockrate != 12288)
1272 printk(KERN_ERR "DBRI: illegal bits_per_frame "
1273 "in setup_chi\n");
1274
1275 *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD
1276 | D_CHI_BPF(bits_per_frame));
1277 }
1278
1279 dbri->chi_bpf = bits_per_frame;
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
1290 *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN);
1291 *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
1292
1293 dbri_cmdsend(dbri, cmd, 4);
1294}
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307static __devinit void cs4215_setup_pipes(struct snd_dbri *dbri)
1308{
1309 unsigned long flags;
1310
1311 spin_lock_irqsave(&dbri->lock, flags);
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327 setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB);
1328 setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
1329 setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB);
1330 setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
1331
1332 setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
1333 setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
1334 setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
1335 spin_unlock_irqrestore(&dbri->lock, flags);
1336
1337 dbri_cmdwait(dbri);
1338}
1339
1340static __devinit int cs4215_init_data(struct cs4215 *mm)
1341{
1342
1343
1344
1345
1346
1347
1348
1349 mm->data[0] = CS4215_LO(0x20) | CS4215_HE | CS4215_LE;
1350 mm->data[1] = CS4215_RO(0x20) | CS4215_SE;
1351 mm->data[2] = CS4215_LG(0x8) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1;
1352 mm->data[3] = CS4215_RG(0x8) | CS4215_MA(0xf);
1353
1354
1355
1356
1357
1358
1359
1360
1361 mm->ctrl[0] = CS4215_RSRVD_1 | CS4215_MLB;
1362 mm->ctrl[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval;
1363 mm->ctrl[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal;
1364 mm->ctrl[3] = 0;
1365
1366 mm->status = 0;
1367 mm->version = 0xff;
1368 mm->precision = 8;
1369 mm->channels = 1;
1370
1371 return 0;
1372}
1373
1374static void cs4215_setdata(struct snd_dbri *dbri, int muted)
1375{
1376 if (muted) {
1377 dbri->mm.data[0] |= 63;
1378 dbri->mm.data[1] |= 63;
1379 dbri->mm.data[2] &= ~15;
1380 dbri->mm.data[3] &= ~15;
1381 } else {
1382
1383 struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
1384 int left_gain = info->left_gain & 0x3f;
1385 int right_gain = info->right_gain & 0x3f;
1386
1387 dbri->mm.data[0] &= ~0x3f;
1388 dbri->mm.data[1] &= ~0x3f;
1389 dbri->mm.data[0] |= (DBRI_MAX_VOLUME - left_gain);
1390 dbri->mm.data[1] |= (DBRI_MAX_VOLUME - right_gain);
1391
1392
1393 info = &dbri->stream_info[DBRI_REC];
1394 left_gain = info->left_gain & 0xf;
1395 right_gain = info->right_gain & 0xf;
1396 dbri->mm.data[2] |= CS4215_LG(left_gain);
1397 dbri->mm.data[3] |= CS4215_RG(right_gain);
1398 }
1399
1400 xmit_fixed(dbri, 20, *(int *)dbri->mm.data);
1401}
1402
1403
1404
1405
1406static void cs4215_open(struct snd_dbri *dbri)
1407{
1408 int data_width;
1409 u32 tmp;
1410 unsigned long flags;
1411
1412 dprintk(D_MM, "cs4215_open: %d channels, %d bits\n",
1413 dbri->mm.channels, dbri->mm.precision);
1414
1415
1416
1417
1418
1419 cs4215_setdata(dbri, 1);
1420 udelay(125);
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 spin_lock_irqsave(&dbri->lock, flags);
1436 tmp = sbus_readl(dbri->regs + REG0);
1437 tmp &= ~(D_C);
1438 sbus_writel(tmp, dbri->regs + REG0);
1439
1440
1441 sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 |
1442 (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2);
1443
1444 reset_chi(dbri, CHIslave, 128);
1445
1446
1447
1448
1449
1450
1451
1452 data_width = dbri->mm.channels * dbri->mm.precision;
1453
1454 link_time_slot(dbri, 4, 16, 16, data_width, dbri->mm.offset);
1455 link_time_slot(dbri, 20, 4, 16, 32, dbri->mm.offset + 32);
1456 link_time_slot(dbri, 6, 16, 16, data_width, dbri->mm.offset);
1457 link_time_slot(dbri, 21, 6, 16, 16, dbri->mm.offset + 40);
1458
1459
1460 tmp = sbus_readl(dbri->regs + REG0);
1461 tmp |= D_C;
1462 sbus_writel(tmp, dbri->regs + REG0);
1463 spin_unlock_irqrestore(&dbri->lock, flags);
1464
1465 cs4215_setdata(dbri, 0);
1466}
1467
1468
1469
1470
1471static int cs4215_setctrl(struct snd_dbri *dbri)
1472{
1473 int i, val;
1474 u32 tmp;
1475 unsigned long flags;
1476
1477
1478
1479
1480
1481
1482 cs4215_setdata(dbri, 1);
1483 udelay(125);
1484
1485
1486
1487
1488
1489 val = D_ENPIO | D_PIO1 | (dbri->mm.onboard ? D_PIO0 : D_PIO2);
1490 sbus_writel(val, dbri->regs + REG2);
1491 dprintk(D_MM, "cs4215_setctrl: reg2=0x%x\n", val);
1492 udelay(34);
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512 spin_lock_irqsave(&dbri->lock, flags);
1513 tmp = sbus_readl(dbri->regs + REG0);
1514 tmp &= ~D_C;
1515 sbus_writel(tmp, dbri->regs + REG0);
1516
1517 reset_chi(dbri, CHImaster, 128);
1518
1519
1520
1521
1522
1523
1524
1525
1526 link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset);
1527 link_time_slot(dbri, 18, 16, 16, 8, dbri->mm.offset);
1528 link_time_slot(dbri, 19, 18, 16, 8, dbri->mm.offset + 48);
1529 spin_unlock_irqrestore(&dbri->lock, flags);
1530
1531
1532 dbri->mm.ctrl[0] &= ~CS4215_CLB;
1533 xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
1534
1535 spin_lock_irqsave(&dbri->lock, flags);
1536 tmp = sbus_readl(dbri->regs + REG0);
1537 tmp |= D_C;
1538 sbus_writel(tmp, dbri->regs + REG0);
1539 spin_unlock_irqrestore(&dbri->lock, flags);
1540
1541 for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i)
1542 msleep_interruptible(1);
1543
1544 if (i == 0) {
1545 dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n",
1546 dbri->mm.status);
1547 return -1;
1548 }
1549
1550
1551
1552
1553 recv_fixed(dbri, 19, NULL);
1554
1555
1556
1557
1558 dbri->mm.ctrl[0] |= CS4215_CLB;
1559 xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
1560
1561
1562 udelay(250);
1563
1564 cs4215_setdata(dbri, 0);
1565
1566 return 0;
1567}
1568
1569
1570
1571
1572
1573
1574
1575static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate,
1576 snd_pcm_format_t format, unsigned int channels)
1577{
1578 int freq_idx;
1579 int ret = 0;
1580
1581
1582 for (freq_idx = 0; CS4215_FREQ[freq_idx].freq != 0; freq_idx++) {
1583 if (CS4215_FREQ[freq_idx].freq == rate)
1584 break;
1585 }
1586 if (CS4215_FREQ[freq_idx].freq != rate) {
1587 printk(KERN_WARNING "DBRI: Unsupported rate %d Hz\n", rate);
1588 return -1;
1589 }
1590
1591 switch (format) {
1592 case SNDRV_PCM_FORMAT_MU_LAW:
1593 dbri->mm.ctrl[1] = CS4215_DFR_ULAW;
1594 dbri->mm.precision = 8;
1595 break;
1596 case SNDRV_PCM_FORMAT_A_LAW:
1597 dbri->mm.ctrl[1] = CS4215_DFR_ALAW;
1598 dbri->mm.precision = 8;
1599 break;
1600 case SNDRV_PCM_FORMAT_U8:
1601 dbri->mm.ctrl[1] = CS4215_DFR_LINEAR8;
1602 dbri->mm.precision = 8;
1603 break;
1604 case SNDRV_PCM_FORMAT_S16_BE:
1605 dbri->mm.ctrl[1] = CS4215_DFR_LINEAR16;
1606 dbri->mm.precision = 16;
1607 break;
1608 default:
1609 printk(KERN_WARNING "DBRI: Unsupported format %d\n", format);
1610 return -1;
1611 }
1612
1613
1614 dbri->mm.ctrl[1] |= CS4215_FREQ[freq_idx].csval;
1615 dbri->mm.ctrl[2] = CS4215_XCLK |
1616 CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal;
1617
1618 dbri->mm.channels = channels;
1619 if (channels == 2)
1620 dbri->mm.ctrl[1] |= CS4215_DFR_STEREO;
1621
1622 ret = cs4215_setctrl(dbri);
1623 if (ret == 0)
1624 cs4215_open(dbri);
1625
1626 return ret;
1627}
1628
1629
1630
1631
1632static __devinit int cs4215_init(struct snd_dbri *dbri)
1633{
1634 u32 reg2 = sbus_readl(dbri->regs + REG2);
1635 dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
1636
1637
1638 if (reg2 & D_PIO2) {
1639 dprintk(D_MM, "Onboard CS4215 detected\n");
1640 dbri->mm.onboard = 1;
1641 }
1642 if (reg2 & D_PIO0) {
1643 dprintk(D_MM, "Speakerbox detected\n");
1644 dbri->mm.onboard = 0;
1645
1646 if (reg2 & D_PIO2) {
1647 printk(KERN_INFO "DBRI: Using speakerbox / "
1648 "ignoring onboard mmcodec.\n");
1649 sbus_writel(D_ENPIO2, dbri->regs + REG2);
1650 }
1651 }
1652
1653 if (!(reg2 & (D_PIO0 | D_PIO2))) {
1654 printk(KERN_ERR "DBRI: no mmcodec found.\n");
1655 return -EIO;
1656 }
1657
1658 cs4215_setup_pipes(dbri);
1659 cs4215_init_data(&dbri->mm);
1660
1661
1662 recv_fixed(dbri, 18, &dbri->mm.status);
1663 recv_fixed(dbri, 19, &dbri->mm.version);
1664
1665 dbri->mm.offset = dbri->mm.onboard ? 0 : 8;
1666 if (cs4215_setctrl(dbri) == -1 || dbri->mm.version == 0xff) {
1667 dprintk(D_MM, "CS4215 failed probe at offset %d\n",
1668 dbri->mm.offset);
1669 return -EIO;
1670 }
1671 dprintk(D_MM, "Found CS4215 at offset %d\n", dbri->mm.offset);
1672
1673 return 0;
1674}
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696static void xmit_descs(struct snd_dbri *dbri)
1697{
1698 struct dbri_streaminfo *info;
1699 s32 *cmd;
1700 unsigned long flags;
1701 int first_td;
1702
1703 if (dbri == NULL)
1704 return;
1705
1706 info = &dbri->stream_info[DBRI_REC];
1707 spin_lock_irqsave(&dbri->lock, flags);
1708
1709 if (info->pipe >= 0) {
1710 first_td = dbri->pipes[info->pipe].first_desc;
1711
1712 dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
1713
1714
1715 if (first_td >= 0) {
1716 cmd = dbri_cmdlock(dbri, 2);
1717 *(cmd++) = DBRI_CMD(D_SDP, 0,
1718 dbri->pipes[info->pipe].sdp
1719 | D_SDP_P | D_SDP_EVERY | D_SDP_C);
1720 *(cmd++) = dbri->dma_dvma +
1721 dbri_dma_off(desc, first_td);
1722 dbri_cmdsend(dbri, cmd, 2);
1723
1724
1725 dbri->pipes[info->pipe].desc = first_td;
1726 }
1727 }
1728
1729 info = &dbri->stream_info[DBRI_PLAY];
1730
1731 if (info->pipe >= 0) {
1732 first_td = dbri->pipes[info->pipe].first_desc;
1733
1734 dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td);
1735
1736
1737 if (first_td >= 0) {
1738 cmd = dbri_cmdlock(dbri, 2);
1739 *(cmd++) = DBRI_CMD(D_SDP, 0,
1740 dbri->pipes[info->pipe].sdp
1741 | D_SDP_P | D_SDP_EVERY | D_SDP_C);
1742 *(cmd++) = dbri->dma_dvma +
1743 dbri_dma_off(desc, first_td);
1744 dbri_cmdsend(dbri, cmd, 2);
1745
1746
1747 dbri->pipes[info->pipe].desc = first_td;
1748 }
1749 }
1750
1751 spin_unlock_irqrestore(&dbri->lock, flags);
1752}
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768static void transmission_complete_intr(struct snd_dbri *dbri, int pipe)
1769{
1770 struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
1771 int td = dbri->pipes[pipe].desc;
1772 int status;
1773
1774 while (td >= 0) {
1775 if (td >= DBRI_NO_DESCS) {
1776 printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe);
1777 return;
1778 }
1779
1780 status = DBRI_TD_STATUS(dbri->dma->desc[td].word4);
1781 if (!(status & DBRI_TD_TBC))
1782 break;
1783
1784 dprintk(D_INT, "TD %d, status 0x%02x\n", td, status);
1785
1786 dbri->dma->desc[td].word4 = 0;
1787 info->offset += DBRI_RD_CNT(dbri->dma->desc[td].word1);
1788
1789 td = dbri->next_desc[td];
1790 dbri->pipes[pipe].desc = td;
1791 }
1792
1793
1794 spin_unlock(&dbri->lock);
1795 snd_pcm_period_elapsed(info->substream);
1796 spin_lock(&dbri->lock);
1797}
1798
1799static void reception_complete_intr(struct snd_dbri *dbri, int pipe)
1800{
1801 struct dbri_streaminfo *info;
1802 int rd = dbri->pipes[pipe].desc;
1803 s32 status;
1804
1805 if (rd < 0 || rd >= DBRI_NO_DESCS) {
1806 printk(KERN_ERR "DBRI: invalid rd on pipe %d\n", pipe);
1807 return;
1808 }
1809
1810 dbri->pipes[pipe].desc = dbri->next_desc[rd];
1811 status = dbri->dma->desc[rd].word1;
1812 dbri->dma->desc[rd].word1 = 0;
1813
1814 info = &dbri->stream_info[DBRI_REC];
1815 info->offset += DBRI_RD_CNT(status);
1816
1817
1818
1819 dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
1820 rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
1821
1822
1823 spin_unlock(&dbri->lock);
1824 snd_pcm_period_elapsed(info->substream);
1825 spin_lock(&dbri->lock);
1826}
1827
1828static void dbri_process_one_interrupt(struct snd_dbri *dbri, int x)
1829{
1830 int val = D_INTR_GETVAL(x);
1831 int channel = D_INTR_GETCHAN(x);
1832 int command = D_INTR_GETCMD(x);
1833 int code = D_INTR_GETCODE(x);
1834#ifdef DBRI_DEBUG
1835 int rval = D_INTR_GETRVAL(x);
1836#endif
1837
1838 if (channel == D_INTR_CMD) {
1839 dprintk(D_CMD, "INTR: Command: %-5s Value:%d\n",
1840 cmds[command], val);
1841 } else {
1842 dprintk(D_INT, "INTR: Chan:%d Code:%d Val:%#x\n",
1843 channel, code, rval);
1844 }
1845
1846 switch (code) {
1847 case D_INTR_CMDI:
1848 if (command != D_WAIT)
1849 printk(KERN_ERR "DBRI: Command read interrupt\n");
1850 break;
1851 case D_INTR_BRDY:
1852 reception_complete_intr(dbri, channel);
1853 break;
1854 case D_INTR_XCMP:
1855 case D_INTR_MINT:
1856 transmission_complete_intr(dbri, channel);
1857 break;
1858 case D_INTR_UNDR:
1859
1860
1861
1862 {
1863
1864 printk(KERN_ERR "DBRI: Underrun error\n");
1865#if 0
1866 s32 *cmd;
1867 int pipe = channel;
1868 int td = dbri->pipes[pipe].desc;
1869
1870 dbri->dma->desc[td].word4 = 0;
1871 cmd = dbri_cmdlock(dbri, NoGetLock);
1872 *(cmd++) = DBRI_CMD(D_SDP, 0,
1873 dbri->pipes[pipe].sdp
1874 | D_SDP_P | D_SDP_C | D_SDP_2SAME);
1875 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td);
1876 dbri_cmdsend(dbri, cmd);
1877#endif
1878 }
1879 break;
1880 case D_INTR_FXDT:
1881
1882 if (dbri->pipes[channel].sdp & D_SDP_MSB)
1883 val = reverse_bytes(val, dbri->pipes[channel].length);
1884
1885 if (dbri->pipes[channel].recv_fixed_ptr)
1886 *(dbri->pipes[channel].recv_fixed_ptr) = val;
1887 break;
1888 default:
1889 if (channel != D_INTR_CMD)
1890 printk(KERN_WARNING
1891 "DBRI: Ignored Interrupt: %d (0x%x)\n", code, x);
1892 }
1893}
1894
1895
1896
1897
1898
1899
1900static void dbri_process_interrupt_buffer(struct snd_dbri *dbri)
1901{
1902 s32 x;
1903
1904 while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) {
1905 dbri->dma->intr[dbri->dbri_irqp] = 0;
1906 dbri->dbri_irqp++;
1907 if (dbri->dbri_irqp == DBRI_INT_BLK)
1908 dbri->dbri_irqp = 1;
1909
1910 dbri_process_one_interrupt(dbri, x);
1911 }
1912}
1913
1914static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id)
1915{
1916 struct snd_dbri *dbri = dev_id;
1917 static int errcnt = 0;
1918 int x;
1919
1920 if (dbri == NULL)
1921 return IRQ_NONE;
1922 spin_lock(&dbri->lock);
1923
1924
1925
1926
1927 x = sbus_readl(dbri->regs + REG1);
1928
1929 if (x & (D_MRR | D_MLE | D_LBG | D_MBE)) {
1930 u32 tmp;
1931
1932 if (x & D_MRR)
1933 printk(KERN_ERR
1934 "DBRI: Multiple Error Ack on SBus reg1=0x%x\n",
1935 x);
1936 if (x & D_MLE)
1937 printk(KERN_ERR
1938 "DBRI: Multiple Late Error on SBus reg1=0x%x\n",
1939 x);
1940 if (x & D_LBG)
1941 printk(KERN_ERR
1942 "DBRI: Lost Bus Grant on SBus reg1=0x%x\n", x);
1943 if (x & D_MBE)
1944 printk(KERN_ERR
1945 "DBRI: Burst Error on SBus reg1=0x%x\n", x);
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955 if ((++errcnt) % 10 == 0) {
1956 dprintk(D_INT, "Interrupt errors exceeded.\n");
1957 dbri_reset(dbri);
1958 } else {
1959 tmp = sbus_readl(dbri->regs + REG0);
1960 tmp &= ~(D_D);
1961 sbus_writel(tmp, dbri->regs + REG0);
1962 }
1963 }
1964
1965 dbri_process_interrupt_buffer(dbri);
1966
1967 spin_unlock(&dbri->lock);
1968
1969 return IRQ_HANDLED;
1970}
1971
1972
1973
1974
1975static struct snd_pcm_hardware snd_dbri_pcm_hw = {
1976 .info = SNDRV_PCM_INFO_MMAP |
1977 SNDRV_PCM_INFO_INTERLEAVED |
1978 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1979 SNDRV_PCM_INFO_MMAP_VALID |
1980 SNDRV_PCM_INFO_BATCH,
1981 .formats = SNDRV_PCM_FMTBIT_MU_LAW |
1982 SNDRV_PCM_FMTBIT_A_LAW |
1983 SNDRV_PCM_FMTBIT_U8 |
1984 SNDRV_PCM_FMTBIT_S16_BE,
1985 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512,
1986 .rate_min = 5512,
1987 .rate_max = 48000,
1988 .channels_min = 1,
1989 .channels_max = 2,
1990 .buffer_bytes_max = 64 * 1024,
1991 .period_bytes_min = 1,
1992 .period_bytes_max = DBRI_TD_MAXCNT,
1993 .periods_min = 1,
1994 .periods_max = 1024,
1995};
1996
1997static int snd_hw_rule_format(struct snd_pcm_hw_params *params,
1998 struct snd_pcm_hw_rule *rule)
1999{
2000 struct snd_interval *c = hw_param_interval(params,
2001 SNDRV_PCM_HW_PARAM_CHANNELS);
2002 struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
2003 struct snd_mask fmt;
2004
2005 snd_mask_any(&fmt);
2006 if (c->min > 1) {
2007 fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_BE;
2008 return snd_mask_refine(f, &fmt);
2009 }
2010 return 0;
2011}
2012
2013static int snd_hw_rule_channels(struct snd_pcm_hw_params *params,
2014 struct snd_pcm_hw_rule *rule)
2015{
2016 struct snd_interval *c = hw_param_interval(params,
2017 SNDRV_PCM_HW_PARAM_CHANNELS);
2018 struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
2019 struct snd_interval ch;
2020
2021 snd_interval_any(&ch);
2022 if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) {
2023 ch.min = 1;
2024 ch.max = 1;
2025 ch.integer = 1;
2026 return snd_interval_refine(c, &ch);
2027 }
2028 return 0;
2029}
2030
2031static int snd_dbri_open(struct snd_pcm_substream *substream)
2032{
2033 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
2034 struct snd_pcm_runtime *runtime = substream->runtime;
2035 struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
2036 unsigned long flags;
2037
2038 dprintk(D_USR, "open audio output.\n");
2039 runtime->hw = snd_dbri_pcm_hw;
2040
2041 spin_lock_irqsave(&dbri->lock, flags);
2042 info->substream = substream;
2043 info->offset = 0;
2044 info->dvma_buffer = 0;
2045 info->pipe = -1;
2046 spin_unlock_irqrestore(&dbri->lock, flags);
2047
2048 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2049 snd_hw_rule_format, NULL, SNDRV_PCM_HW_PARAM_FORMAT,
2050 -1);
2051 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
2052 snd_hw_rule_channels, NULL,
2053 SNDRV_PCM_HW_PARAM_CHANNELS,
2054 -1);
2055
2056 cs4215_open(dbri);
2057
2058 return 0;
2059}
2060
2061static int snd_dbri_close(struct snd_pcm_substream *substream)
2062{
2063 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
2064 struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
2065
2066 dprintk(D_USR, "close audio output.\n");
2067 info->substream = NULL;
2068 info->offset = 0;
2069
2070 return 0;
2071}
2072
2073static int snd_dbri_hw_params(struct snd_pcm_substream *substream,
2074 struct snd_pcm_hw_params *hw_params)
2075{
2076 struct snd_pcm_runtime *runtime = substream->runtime;
2077 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
2078 struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
2079 int direction;
2080 int ret;
2081
2082
2083 ret = cs4215_prepare(dbri, params_rate(hw_params),
2084 params_format(hw_params),
2085 params_channels(hw_params));
2086 if (ret != 0)
2087 return ret;
2088
2089 if ((ret = snd_pcm_lib_malloc_pages(substream,
2090 params_buffer_bytes(hw_params))) < 0) {
2091 printk(KERN_ERR "malloc_pages failed with %d\n", ret);
2092 return ret;
2093 }
2094
2095
2096
2097 if (info->dvma_buffer == 0) {
2098 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2099 direction = DMA_TO_DEVICE;
2100 else
2101 direction = DMA_FROM_DEVICE;
2102
2103 info->dvma_buffer =
2104 dma_map_single(&dbri->op->dev,
2105 runtime->dma_area,
2106 params_buffer_bytes(hw_params),
2107 direction);
2108 }
2109
2110 direction = params_buffer_bytes(hw_params);
2111 dprintk(D_USR, "hw_params: %d bytes, dvma=%x\n",
2112 direction, info->dvma_buffer);
2113 return 0;
2114}
2115
2116static int snd_dbri_hw_free(struct snd_pcm_substream *substream)
2117{
2118 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
2119 struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
2120 int direction;
2121
2122 dprintk(D_USR, "hw_free.\n");
2123
2124
2125
2126 if (info->dvma_buffer) {
2127 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2128 direction = DMA_TO_DEVICE;
2129 else
2130 direction = DMA_FROM_DEVICE;
2131
2132 dma_unmap_single(&dbri->op->dev, info->dvma_buffer,
2133 substream->runtime->buffer_size, direction);
2134 info->dvma_buffer = 0;
2135 }
2136 if (info->pipe != -1) {
2137 reset_pipe(dbri, info->pipe);
2138 info->pipe = -1;
2139 }
2140
2141 return snd_pcm_lib_free_pages(substream);
2142}
2143
2144static int snd_dbri_prepare(struct snd_pcm_substream *substream)
2145{
2146 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
2147 struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
2148 int ret;
2149
2150 info->size = snd_pcm_lib_buffer_bytes(substream);
2151 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2152 info->pipe = 4;
2153 else
2154 info->pipe = 6;
2155
2156 spin_lock_irq(&dbri->lock);
2157 info->offset = 0;
2158
2159
2160
2161
2162 ret = setup_descs(dbri, DBRI_STREAMNO(substream),
2163 snd_pcm_lib_period_bytes(substream));
2164
2165 spin_unlock_irq(&dbri->lock);
2166
2167 dprintk(D_USR, "prepare audio output. %d bytes\n", info->size);
2168 return ret;
2169}
2170
2171static int snd_dbri_trigger(struct snd_pcm_substream *substream, int cmd)
2172{
2173 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
2174 struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
2175 int ret = 0;
2176
2177 switch (cmd) {
2178 case SNDRV_PCM_TRIGGER_START:
2179 dprintk(D_USR, "start audio, period is %d bytes\n",
2180 (int)snd_pcm_lib_period_bytes(substream));
2181
2182 xmit_descs(dbri);
2183 break;
2184 case SNDRV_PCM_TRIGGER_STOP:
2185 dprintk(D_USR, "stop audio.\n");
2186 reset_pipe(dbri, info->pipe);
2187 break;
2188 default:
2189 ret = -EINVAL;
2190 }
2191
2192 return ret;
2193}
2194
2195static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream)
2196{
2197 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
2198 struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
2199 snd_pcm_uframes_t ret;
2200
2201 ret = bytes_to_frames(substream->runtime, info->offset)
2202 % substream->runtime->buffer_size;
2203 dprintk(D_USR, "I/O pointer: %ld frames of %ld.\n",
2204 ret, substream->runtime->buffer_size);
2205 return ret;
2206}
2207
2208static struct snd_pcm_ops snd_dbri_ops = {
2209 .open = snd_dbri_open,
2210 .close = snd_dbri_close,
2211 .ioctl = snd_pcm_lib_ioctl,
2212 .hw_params = snd_dbri_hw_params,
2213 .hw_free = snd_dbri_hw_free,
2214 .prepare = snd_dbri_prepare,
2215 .trigger = snd_dbri_trigger,
2216 .pointer = snd_dbri_pointer,
2217};
2218
2219static int __devinit snd_dbri_pcm(struct snd_card *card)
2220{
2221 struct snd_pcm *pcm;
2222 int err;
2223
2224 if ((err = snd_pcm_new(card,
2225 "sun_dbri",
2226 0,
2227 1,
2228 1, &pcm)) < 0)
2229 return err;
2230
2231 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
2232 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);
2233
2234 pcm->private_data = card->private_data;
2235 pcm->info_flags = 0;
2236 strcpy(pcm->name, card->shortname);
2237
2238 if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm,
2239 SNDRV_DMA_TYPE_CONTINUOUS,
2240 snd_dma_continuous_data(GFP_KERNEL),
2241 64 * 1024, 64 * 1024)) < 0)
2242 return err;
2243
2244 return 0;
2245}
2246
2247
2248
2249
2250
2251static int snd_cs4215_info_volume(struct snd_kcontrol *kcontrol,
2252 struct snd_ctl_elem_info *uinfo)
2253{
2254 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2255 uinfo->count = 2;
2256 uinfo->value.integer.min = 0;
2257 if (kcontrol->private_value == DBRI_PLAY)
2258 uinfo->value.integer.max = DBRI_MAX_VOLUME;
2259 else
2260 uinfo->value.integer.max = DBRI_MAX_GAIN;
2261 return 0;
2262}
2263
2264static int snd_cs4215_get_volume(struct snd_kcontrol *kcontrol,
2265 struct snd_ctl_elem_value *ucontrol)
2266{
2267 struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
2268 struct dbri_streaminfo *info;
2269
2270 if (snd_BUG_ON(!dbri))
2271 return -EINVAL;
2272 info = &dbri->stream_info[kcontrol->private_value];
2273
2274 ucontrol->value.integer.value[0] = info->left_gain;
2275 ucontrol->value.integer.value[1] = info->right_gain;
2276 return 0;
2277}
2278
2279static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol,
2280 struct snd_ctl_elem_value *ucontrol)
2281{
2282 struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
2283 struct dbri_streaminfo *info =
2284 &dbri->stream_info[kcontrol->private_value];
2285 unsigned int vol[2];
2286 int changed = 0;
2287
2288 vol[0] = ucontrol->value.integer.value[0];
2289 vol[1] = ucontrol->value.integer.value[1];
2290 if (kcontrol->private_value == DBRI_PLAY) {
2291 if (vol[0] > DBRI_MAX_VOLUME || vol[1] > DBRI_MAX_VOLUME)
2292 return -EINVAL;
2293 } else {
2294 if (vol[0] > DBRI_MAX_GAIN || vol[1] > DBRI_MAX_GAIN)
2295 return -EINVAL;
2296 }
2297
2298 if (info->left_gain != vol[0]) {
2299 info->left_gain = vol[0];
2300 changed = 1;
2301 }
2302 if (info->right_gain != vol[1]) {
2303 info->right_gain = vol[1];
2304 changed = 1;
2305 }
2306 if (changed) {
2307
2308
2309
2310 cs4215_setdata(dbri, 1);
2311 udelay(125);
2312 cs4215_setdata(dbri, 0);
2313 }
2314 return changed;
2315}
2316
2317static int snd_cs4215_info_single(struct snd_kcontrol *kcontrol,
2318 struct snd_ctl_elem_info *uinfo)
2319{
2320 int mask = (kcontrol->private_value >> 16) & 0xff;
2321
2322 uinfo->type = (mask == 1) ?
2323 SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2324 uinfo->count = 1;
2325 uinfo->value.integer.min = 0;
2326 uinfo->value.integer.max = mask;
2327 return 0;
2328}
2329
2330static int snd_cs4215_get_single(struct snd_kcontrol *kcontrol,
2331 struct snd_ctl_elem_value *ucontrol)
2332{
2333 struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
2334 int elem = kcontrol->private_value & 0xff;
2335 int shift = (kcontrol->private_value >> 8) & 0xff;
2336 int mask = (kcontrol->private_value >> 16) & 0xff;
2337 int invert = (kcontrol->private_value >> 24) & 1;
2338
2339 if (snd_BUG_ON(!dbri))
2340 return -EINVAL;
2341
2342 if (elem < 4)
2343 ucontrol->value.integer.value[0] =
2344 (dbri->mm.data[elem] >> shift) & mask;
2345 else
2346 ucontrol->value.integer.value[0] =
2347 (dbri->mm.ctrl[elem - 4] >> shift) & mask;
2348
2349 if (invert == 1)
2350 ucontrol->value.integer.value[0] =
2351 mask - ucontrol->value.integer.value[0];
2352 return 0;
2353}
2354
2355static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol,
2356 struct snd_ctl_elem_value *ucontrol)
2357{
2358 struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
2359 int elem = kcontrol->private_value & 0xff;
2360 int shift = (kcontrol->private_value >> 8) & 0xff;
2361 int mask = (kcontrol->private_value >> 16) & 0xff;
2362 int invert = (kcontrol->private_value >> 24) & 1;
2363 int changed = 0;
2364 unsigned short val;
2365
2366 if (snd_BUG_ON(!dbri))
2367 return -EINVAL;
2368
2369 val = (ucontrol->value.integer.value[0] & mask);
2370 if (invert == 1)
2371 val = mask - val;
2372 val <<= shift;
2373
2374 if (elem < 4) {
2375 dbri->mm.data[elem] = (dbri->mm.data[elem] &
2376 ~(mask << shift)) | val;
2377 changed = (val != dbri->mm.data[elem]);
2378 } else {
2379 dbri->mm.ctrl[elem - 4] = (dbri->mm.ctrl[elem - 4] &
2380 ~(mask << shift)) | val;
2381 changed = (val != dbri->mm.ctrl[elem - 4]);
2382 }
2383
2384 dprintk(D_GEN, "put_single: mask=0x%x, changed=%d, "
2385 "mixer-value=%ld, mm-value=0x%x\n",
2386 mask, changed, ucontrol->value.integer.value[0],
2387 dbri->mm.data[elem & 3]);
2388
2389 if (changed) {
2390
2391
2392
2393 cs4215_setdata(dbri, 1);
2394 udelay(125);
2395 cs4215_setdata(dbri, 0);
2396 }
2397 return changed;
2398}
2399
2400
2401
2402
2403
2404#define CS4215_SINGLE(xname, entry, shift, mask, invert) \
2405{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
2406 .info = snd_cs4215_info_single, \
2407 .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \
2408 .private_value = (entry) | ((shift) << 8) | ((mask) << 16) | \
2409 ((invert) << 24) },
2410
2411static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
2412 {
2413 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2414 .name = "Playback Volume",
2415 .info = snd_cs4215_info_volume,
2416 .get = snd_cs4215_get_volume,
2417 .put = snd_cs4215_put_volume,
2418 .private_value = DBRI_PLAY,
2419 },
2420 CS4215_SINGLE("Headphone switch", 0, 7, 1, 0)
2421 CS4215_SINGLE("Line out switch", 0, 6, 1, 0)
2422 CS4215_SINGLE("Speaker switch", 1, 6, 1, 0)
2423 {
2424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2425 .name = "Capture Volume",
2426 .info = snd_cs4215_info_volume,
2427 .get = snd_cs4215_get_volume,
2428 .put = snd_cs4215_put_volume,
2429 .private_value = DBRI_REC,
2430 },
2431
2432 CS4215_SINGLE("Line in switch", 2, 4, 1, 0)
2433 CS4215_SINGLE("High Pass Filter switch", 5, 7, 1, 0)
2434 CS4215_SINGLE("Monitor Volume", 3, 4, 0xf, 1)
2435 CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
2436};
2437
2438static int __devinit snd_dbri_mixer(struct snd_card *card)
2439{
2440 int idx, err;
2441 struct snd_dbri *dbri;
2442
2443 if (snd_BUG_ON(!card || !card->private_data))
2444 return -EINVAL;
2445 dbri = card->private_data;
2446
2447 strcpy(card->mixername, card->shortname);
2448
2449 for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
2450 err = snd_ctl_add(card,
2451 snd_ctl_new1(&dbri_controls[idx], dbri));
2452 if (err < 0)
2453 return err;
2454 }
2455
2456 for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) {
2457 dbri->stream_info[idx].left_gain = 0;
2458 dbri->stream_info[idx].right_gain = 0;
2459 }
2460
2461 return 0;
2462}
2463
2464
2465
2466
2467static void dbri_regs_read(struct snd_info_entry *entry,
2468 struct snd_info_buffer *buffer)
2469{
2470 struct snd_dbri *dbri = entry->private_data;
2471
2472 snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0));
2473 snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2));
2474 snd_iprintf(buffer, "REG8: 0x%x\n", sbus_readl(dbri->regs + REG8));
2475 snd_iprintf(buffer, "REG9: 0x%x\n", sbus_readl(dbri->regs + REG9));
2476}
2477
2478#ifdef DBRI_DEBUG
2479static void dbri_debug_read(struct snd_info_entry *entry,
2480 struct snd_info_buffer *buffer)
2481{
2482 struct snd_dbri *dbri = entry->private_data;
2483 int pipe;
2484 snd_iprintf(buffer, "debug=%d\n", dbri_debug);
2485
2486 for (pipe = 0; pipe < 32; pipe++) {
2487 if (pipe_active(dbri, pipe)) {
2488 struct dbri_pipe *pptr = &dbri->pipes[pipe];
2489 snd_iprintf(buffer,
2490 "Pipe %d: %s SDP=0x%x desc=%d, "
2491 "len=%d next %d\n",
2492 pipe,
2493 (pptr->sdp & D_SDP_TO_SER) ? "output" :
2494 "input",
2495 pptr->sdp, pptr->desc,
2496 pptr->length, pptr->nextpipe);
2497 }
2498 }
2499}
2500#endif
2501
2502static void __devinit snd_dbri_proc(struct snd_card *card)
2503{
2504 struct snd_dbri *dbri = card->private_data;
2505 struct snd_info_entry *entry;
2506
2507 if (!snd_card_proc_new(card, "regs", &entry))
2508 snd_info_set_text_ops(entry, dbri, dbri_regs_read);
2509
2510#ifdef DBRI_DEBUG
2511 if (!snd_card_proc_new(card, "debug", &entry)) {
2512 snd_info_set_text_ops(entry, dbri, dbri_debug_read);
2513 entry->mode = S_IFREG | S_IRUGO;
2514 }
2515#endif
2516}
2517
2518
2519
2520
2521
2522
2523static void snd_dbri_free(struct snd_dbri *dbri);
2524
2525static int __devinit snd_dbri_create(struct snd_card *card,
2526 struct platform_device *op,
2527 int irq, int dev)
2528{
2529 struct snd_dbri *dbri = card->private_data;
2530 int err;
2531
2532 spin_lock_init(&dbri->lock);
2533 dbri->op = op;
2534 dbri->irq = irq;
2535
2536 dbri->dma = dma_alloc_coherent(&op->dev,
2537 sizeof(struct dbri_dma),
2538 &dbri->dma_dvma, GFP_ATOMIC);
2539 if (!dbri->dma)
2540 return -ENOMEM;
2541 memset((void *)dbri->dma, 0, sizeof(struct dbri_dma));
2542
2543 dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
2544 dbri->dma, dbri->dma_dvma);
2545
2546
2547 dbri->regs_size = resource_size(&op->resource[0]);
2548 dbri->regs = of_ioremap(&op->resource[0], 0,
2549 dbri->regs_size, "DBRI Registers");
2550 if (!dbri->regs) {
2551 printk(KERN_ERR "DBRI: could not allocate registers\n");
2552 dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
2553 (void *)dbri->dma, dbri->dma_dvma);
2554 return -EIO;
2555 }
2556
2557 err = request_irq(dbri->irq, snd_dbri_interrupt, IRQF_SHARED,
2558 "DBRI audio", dbri);
2559 if (err) {
2560 printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
2561 of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size);
2562 dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
2563 (void *)dbri->dma, dbri->dma_dvma);
2564 return err;
2565 }
2566
2567
2568 dbri_initialize(dbri);
2569 err = cs4215_init(dbri);
2570 if (err) {
2571 snd_dbri_free(dbri);
2572 return err;
2573 }
2574
2575 return 0;
2576}
2577
2578static void snd_dbri_free(struct snd_dbri *dbri)
2579{
2580 dprintk(D_GEN, "snd_dbri_free\n");
2581 dbri_reset(dbri);
2582
2583 if (dbri->irq)
2584 free_irq(dbri->irq, dbri);
2585
2586 if (dbri->regs)
2587 of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size);
2588
2589 if (dbri->dma)
2590 dma_free_coherent(&dbri->op->dev,
2591 sizeof(struct dbri_dma),
2592 (void *)dbri->dma, dbri->dma_dvma);
2593}
2594
2595static int __devinit dbri_probe(struct platform_device *op, const struct of_device_id *match)
2596{
2597 struct snd_dbri *dbri;
2598 struct resource *rp;
2599 struct snd_card *card;
2600 static int dev = 0;
2601 int irq;
2602 int err;
2603
2604 if (dev >= SNDRV_CARDS)
2605 return -ENODEV;
2606 if (!enable[dev]) {
2607 dev++;
2608 return -ENOENT;
2609 }
2610
2611 irq = op->archdata.irqs[0];
2612 if (irq <= 0) {
2613 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
2614 return -ENODEV;
2615 }
2616
2617 err = snd_card_create(index[dev], id[dev], THIS_MODULE,
2618 sizeof(struct snd_dbri), &card);
2619 if (err < 0)
2620 return err;
2621
2622 strcpy(card->driver, "DBRI");
2623 strcpy(card->shortname, "Sun DBRI");
2624 rp = &op->resource[0];
2625 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
2626 card->shortname,
2627 rp->flags & 0xffL, (unsigned long long)rp->start, irq);
2628
2629 err = snd_dbri_create(card, op, irq, dev);
2630 if (err < 0) {
2631 snd_card_free(card);
2632 return err;
2633 }
2634
2635 dbri = card->private_data;
2636 err = snd_dbri_pcm(card);
2637 if (err < 0)
2638 goto _err;
2639
2640 err = snd_dbri_mixer(card);
2641 if (err < 0)
2642 goto _err;
2643
2644
2645 snd_dbri_proc(card);
2646 dev_set_drvdata(&op->dev, card);
2647
2648 err = snd_card_register(card);
2649 if (err < 0)
2650 goto _err;
2651
2652 printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
2653 dev, dbri->regs,
2654 dbri->irq, op->dev.of_node->name[9], dbri->mm.version);
2655 dev++;
2656
2657 return 0;
2658
2659_err:
2660 snd_dbri_free(dbri);
2661 snd_card_free(card);
2662 return err;
2663}
2664
2665static int __devexit dbri_remove(struct platform_device *op)
2666{
2667 struct snd_card *card = dev_get_drvdata(&op->dev);
2668
2669 snd_dbri_free(card->private_data);
2670 snd_card_free(card);
2671
2672 dev_set_drvdata(&op->dev, NULL);
2673
2674 return 0;
2675}
2676
2677static const struct of_device_id dbri_match[] = {
2678 {
2679 .name = "SUNW,DBRIe",
2680 },
2681 {
2682 .name = "SUNW,DBRIf",
2683 },
2684 {},
2685};
2686
2687MODULE_DEVICE_TABLE(of, dbri_match);
2688
2689static struct of_platform_driver dbri_sbus_driver = {
2690 .driver = {
2691 .name = "dbri",
2692 .owner = THIS_MODULE,
2693 .of_match_table = dbri_match,
2694 },
2695 .probe = dbri_probe,
2696 .remove = __devexit_p(dbri_remove),
2697};
2698
2699
2700static int __init dbri_init(void)
2701{
2702 return of_register_platform_driver(&dbri_sbus_driver);
2703}
2704
2705static void __exit dbri_exit(void)
2706{
2707 of_unregister_platform_driver(&dbri_sbus_driver);
2708}
2709
2710module_init(dbri_init);
2711module_exit(dbri_exit);
2712