1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#define VIA_VERSION "1.9.1-ac3"
19
20
21#include <linux/config.h>
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/fs.h>
25#include <linux/mm.h>
26#include <linux/pci.h>
27#include <linux/init.h>
28#include <linux/proc_fs.h>
29#include <linux/spinlock.h>
30#include <linux/sound.h>
31#include <linux/poll.h>
32#include <linux/soundcard.h>
33#include <linux/ac97_codec.h>
34#include <linux/smp_lock.h>
35#include <linux/ioport.h>
36#include <linux/wrapper.h>
37#include <linux/delay.h>
38#include <asm/io.h>
39#include <asm/uaccess.h>
40#include <asm/hardirq.h>
41#include <asm/semaphore.h>
42#include "sound_config.h"
43#include "dev_table.h"
44#include "mpu401.h"
45
46
47#undef VIA_DEBUG
48#ifdef VIA_DEBUG
49
50#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
51#else
52#define DPRINTK(fmt, args...)
53#endif
54
55#undef VIA_NDEBUG
56#ifdef VIA_NDEBUG
57#define assert(expr)
58#else
59#define assert(expr) \
60 if(!(expr)) { \
61 printk( "Assertion failed! %s,%s,%s,line=%d\n", \
62 #expr,__FILE__,__FUNCTION__,__LINE__); \
63 }
64#endif
65
66#define VIA_SUPPORT_MMAP 1
67
68#define MAX_CARDS 1
69
70#define VIA_CARD_NAME "VIA 82Cxxx Audio driver " VIA_VERSION
71#define VIA_MODULE_NAME "via82cxxx"
72#define PFX VIA_MODULE_NAME ": "
73
74#define VIA_COUNTER_LIMIT 100000
75
76
77#define VIA_MAX_BUFFER_DMA_PAGES 32
78
79
80#define VIA_DEFAULT_FRAG_TIME 20
81#define VIA_DEFAULT_BUFFER_TIME 500
82
83
84#define VIA_MIN_FRAG_NUMBER 2
85#define VIA_MAX_FRAG_NUMBER 128
86
87#define VIA_MAX_FRAG_SIZE PAGE_SIZE
88#define VIA_MIN_FRAG_SIZE (VIA_MAX_BUFFER_DMA_PAGES * PAGE_SIZE / VIA_MAX_FRAG_NUMBER)
89
90
91
92#define VIA_ACLINK_STATUS 0x40
93#define VIA_ACLINK_CTRL 0x41
94#define VIA_FUNC_ENABLE 0x42
95#define VIA_PNP_CONTROL 0x43
96#define VIA_FM_NMI_CTRL 0x48
97
98
99
100
101
102
103
104
105
106
107#define VIA_BASE0_PCM_OUT_CHAN 0x00
108#define VIA_BASE0_PCM_OUT_CHAN_STATUS 0x00
109#define VIA_BASE0_PCM_OUT_CHAN_CTRL 0x01
110#define VIA_BASE0_PCM_OUT_CHAN_TYPE 0x02
111
112#define VIA_BASE0_PCM_IN_CHAN 0x10
113#define VIA_BASE0_PCM_IN_CHAN_STATUS 0x10
114#define VIA_BASE0_PCM_IN_CHAN_CTRL 0x11
115#define VIA_BASE0_PCM_IN_CHAN_TYPE 0x12
116
117
118#define VIA_PCM_STATUS 0x00
119#define VIA_PCM_CONTROL 0x01
120#define VIA_PCM_TYPE 0x02
121#define VIA_PCM_LEFTVOL 0x02
122#define VIA_PCM_RIGHTVOL 0x03
123#define VIA_PCM_TABLE_ADDR 0x04
124#define VIA_PCM_STOPRATE 0x08
125#define VIA_PCM_BLOCK_COUNT 0x0C
126
127
128#define VIA_BASE0_FM_OUT_CHAN 0x20
129#define VIA_BASE0_FM_OUT_CHAN_STATUS 0x20
130#define VIA_BASE0_FM_OUT_CHAN_CTRL 0x21
131#define VIA_BASE0_FM_OUT_CHAN_TYPE 0x22
132
133
134#define VIA_BASE0_MULTI_OUT_CHAN 0x40
135#define VIA_BASE0_MULTI_OUT_CHAN_STATUS 0x40
136#define VIA_BASE0_MULTI_OUT_CHAN_CTRL 0x41
137#define VIA_BASE0_MULTI_OUT_CHAN_TYPE 0x42
138
139#define VIA_BASE0_AC97_CTRL 0x80
140#define VIA_BASE0_SGD_STATUS_SHADOW 0x84
141#define VIA_BASE0_GPI_INT_ENABLE 0x8C
142#define VIA_INTR_OUT ((1<<0) | (1<<4) | (1<<8))
143#define VIA_INTR_IN ((1<<1) | (1<<5) | (1<<9))
144#define VIA_INTR_FM ((1<<2) | (1<<6) | (1<<10))
145#define VIA_INTR_MASK (VIA_INTR_OUT | VIA_INTR_IN | VIA_INTR_FM)
146
147
148
149
150
151#define VIA_NEW_INTR_MASK 0x77077777UL
152
153
154#define VIA_IRQ_ON_FLAG (1<<0)
155#define VIA_IRQ_ON_EOL (1<<1)
156#define VIA_INT_SEL_PCI_LAST_LINE_READ (0)
157#define VIA_INT_SEL_LAST_SAMPLE_SENT (1<<2)
158#define VIA_INT_SEL_ONE_LINE_LEFT (1<<3)
159#define VIA_PCM_FMT_STEREO (1<<4)
160#define VIA_PCM_FMT_16BIT (1<<5)
161#define VIA_PCM_REC_FIFO (1<<6)
162#define VIA_RESTART_SGD_ON_EOL (1<<7)
163#define VIA_PCM_FMT_MASK (VIA_PCM_FMT_STEREO|VIA_PCM_FMT_16BIT)
164#define VIA_CHAN_TYPE_MASK (VIA_RESTART_SGD_ON_EOL | \
165 VIA_IRQ_ON_FLAG | \
166 VIA_IRQ_ON_EOL)
167#define VIA_CHAN_TYPE_INT_SELECT (VIA_INT_SEL_LAST_SAMPLE_SENT)
168
169
170#define VIA_CR40_AC97_READY 0x01
171#define VIA_CR40_AC97_LOW_POWER 0x02
172#define VIA_CR40_SECONDARY_READY 0x04
173
174#define VIA_CR41_AC97_ENABLE 0x80
175#define VIA_CR41_AC97_RESET 0x40
176#define VIA_CR41_AC97_WAKEUP 0x20
177#define VIA_CR41_AC97_SDO 0x10
178#define VIA_CR41_VRA 0x08
179#define VIA_CR41_PCM_ENABLE 0x04
180#define VIA_CR41_FM_PCM_ENABLE 0x02
181#define VIA_CR41_SB_PCM_ENABLE 0x01
182#define VIA_CR41_BOOT_MASK (VIA_CR41_AC97_ENABLE | \
183 VIA_CR41_AC97_WAKEUP | \
184 VIA_CR41_AC97_SDO)
185#define VIA_CR41_RUN_MASK (VIA_CR41_AC97_ENABLE | \
186 VIA_CR41_AC97_RESET | \
187 VIA_CR41_VRA | \
188 VIA_CR41_PCM_ENABLE)
189
190#define VIA_CR42_SB_ENABLE 0x01
191#define VIA_CR42_MIDI_ENABLE 0x02
192#define VIA_CR42_FM_ENABLE 0x04
193#define VIA_CR42_GAME_ENABLE 0x08
194#define VIA_CR42_MIDI_IRQMASK 0x40
195#define VIA_CR42_MIDI_PNP 0x80
196
197#define VIA_CR44_SECOND_CODEC_SUPPORT (1 << 6)
198#define VIA_CR44_AC_LINK_ACCESS (1 << 7)
199
200#define VIA_CR48_FM_TRAP_TO_NMI (1 << 2)
201
202
203#define VIA_INT_DISABLE_MASK (~(0x01|0x02))
204#define VIA_SGD_STOPPED (1 << 2)
205#define VIA_SGD_PAUSED (1 << 6)
206#define VIA_SGD_ACTIVE (1 << 7)
207#define VIA_SGD_TERMINATE (1 << 6)
208#define VIA_SGD_FLAG (1 << 0)
209#define VIA_SGD_EOL (1 << 1)
210#define VIA_SGD_START (1 << 7)
211
212#define VIA_CR80_FIRST_CODEC 0
213#define VIA_CR80_SECOND_CODEC (1 << 30)
214#define VIA_CR80_FIRST_CODEC_VALID (1 << 25)
215#define VIA_CR80_VALID (1 << 25)
216#define VIA_CR80_SECOND_CODEC_VALID (1 << 27)
217#define VIA_CR80_BUSY (1 << 24)
218#define VIA_CR83_BUSY (1)
219#define VIA_CR83_FIRST_CODEC_VALID (1 << 1)
220#define VIA_CR80_READ (1 << 23)
221#define VIA_CR80_WRITE_MODE 0
222#define VIA_CR80_REG_IDX(idx) ((((idx) & 0xFF) >> 1) << 16)
223
224
225#ifdef VIA_SUPPORT_MMAP
226#define VIA_DSP_CAP (DSP_CAP_REVISION | DSP_CAP_DUPLEX | DSP_CAP_MMAP | \
227 DSP_CAP_TRIGGER | DSP_CAP_REALTIME)
228#else
229#define VIA_DSP_CAP (DSP_CAP_REVISION | DSP_CAP_DUPLEX | \
230 DSP_CAP_TRIGGER | DSP_CAP_REALTIME)
231#endif
232
233
234struct via_sgd_table {
235 u32 addr;
236 u32 count;
237};
238
239#define VIA_EOL (1 << 31)
240#define VIA_FLAG (1 << 30)
241#define VIA_STOP (1 << 29)
242
243
244enum via_channel_states {
245 sgd_stopped = 0,
246 sgd_in_progress = 1,
247};
248
249
250struct via_buffer_pgtbl {
251 dma_addr_t handle;
252 void *cpuaddr;
253};
254
255
256struct via_channel {
257 atomic_t n_frags;
258 atomic_t hw_ptr;
259 wait_queue_head_t wait;
260
261 unsigned int sw_ptr;
262 unsigned int slop_len;
263 unsigned int n_irqs;
264 int bytes;
265
266 unsigned is_active : 1;
267 unsigned is_record : 1;
268 unsigned is_mapped : 1;
269 unsigned is_enabled : 1;
270 unsigned is_multi: 1;
271 u8 pcm_fmt;
272 u8 channels;
273
274 unsigned rate;
275 unsigned int frag_size;
276 unsigned int frag_number;
277
278 unsigned char intmask;
279
280 volatile struct via_sgd_table *sgtable;
281 dma_addr_t sgt_handle;
282
283 unsigned int page_number;
284 struct via_buffer_pgtbl pgtbl[VIA_MAX_BUFFER_DMA_PAGES];
285
286 long iobase;
287
288 const char *name;
289};
290
291
292
293struct via_info {
294 struct pci_dev *pdev;
295 long baseaddr;
296
297 struct ac97_codec *ac97;
298 spinlock_t ac97_lock;
299 spinlock_t lock;
300 int card_num;
301
302 int dev_dsp;
303
304 unsigned rev_h : 1;
305 unsigned legacy: 1;
306 unsigned intmask: 1;
307 unsigned sixchannel: 1;
308 unsigned volume: 1;
309
310 int locked_rate : 1;
311
312 int mixer_vol;
313
314 struct semaphore syscall_sem;
315 struct semaphore open_sem;
316
317
318
319
320
321
322 struct via_channel ch_in;
323 struct via_channel ch_out;
324 struct via_channel ch_fm;
325
326#ifdef CONFIG_MIDI_VIA82CXXX
327 void *midi_devc;
328 struct address_info midi_info;
329#endif
330};
331
332
333
334static unsigned via_num_cards = 0;
335
336
337
338
339
340
341
342
343
344
345static int via_init_one (struct pci_dev *dev, const struct pci_device_id *id);
346static void __devexit via_remove_one (struct pci_dev *pdev);
347
348static ssize_t via_dsp_read(struct file *file, char *buffer, size_t count, loff_t *ppos);
349static ssize_t via_dsp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos);
350static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wait);
351static int via_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
352static int via_dsp_open (struct inode *inode, struct file *file);
353static int via_dsp_release(struct inode *inode, struct file *file);
354static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma);
355
356static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg);
357static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value);
358static u8 via_ac97_wait_idle (struct via_info *card);
359
360static void via_chan_free (struct via_info *card, struct via_channel *chan);
361static void via_chan_clear (struct via_info *card, struct via_channel *chan);
362static void via_chan_pcm_fmt (struct via_channel *chan, int reset);
363static void via_chan_buffer_free (struct via_info *card, struct via_channel *chan);
364
365#ifdef CONFIG_PROC_FS
366static int via_init_proc (void);
367static void via_cleanup_proc (void);
368static int via_card_init_proc (struct via_info *card);
369static void via_card_cleanup_proc (struct via_info *card);
370#else
371static inline int via_init_proc (void) { return 0; }
372static inline void via_cleanup_proc (void) {}
373static inline int via_card_init_proc (struct via_info *card) { return 0; }
374static inline void via_card_cleanup_proc (struct via_info *card) {}
375#endif
376
377
378
379
380
381
382
383
384
385
386static struct pci_device_id via_pci_tbl[] __initdata = {
387 { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
388 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
389 { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5,
390 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
391 { 0, }
392};
393MODULE_DEVICE_TABLE(pci,via_pci_tbl);
394
395
396static struct pci_driver via_driver = {
397 name: VIA_MODULE_NAME,
398 id_table: via_pci_tbl,
399 probe: via_init_one,
400 remove: __devexit_p(via_remove_one),
401};
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424static inline void via_chan_stop (long iobase)
425{
426 if (inb (iobase + VIA_PCM_STATUS) & VIA_SGD_ACTIVE)
427 outb (VIA_SGD_TERMINATE, iobase + VIA_PCM_CONTROL);
428}
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445static inline void via_chan_status_clear (long iobase)
446{
447 u8 tmp = inb (iobase + VIA_PCM_STATUS);
448
449 if (tmp != 0)
450 outb (tmp, iobase + VIA_PCM_STATUS);
451}
452
453
454
455
456
457
458
459
460
461
462static inline void sg_begin (struct via_channel *chan)
463{
464 DPRINTK("Start with intmask %d\n", chan->intmask);
465 DPRINTK("About to start from %d to %d\n",
466 inl(chan->iobase + VIA_PCM_BLOCK_COUNT),
467 inb(chan->iobase + VIA_PCM_STOPRATE + 3));
468 outb (VIA_SGD_START|chan->intmask, chan->iobase + VIA_PCM_CONTROL);
469 DPRINTK("Status is now %02X\n", inb(chan->iobase + VIA_PCM_STATUS));
470 DPRINTK("Control is now %02X\n", inb(chan->iobase + VIA_PCM_CONTROL));
471}
472
473
474static int sg_active (long iobase)
475{
476 u8 tmp = inb (iobase + VIA_PCM_STATUS);
477 if ((tmp & VIA_SGD_STOPPED) || (tmp & VIA_SGD_PAUSED)) {
478 printk(KERN_WARNING "via82cxxx warning: SG stopped or paused\n");
479 return 0;
480 }
481 if (tmp & VIA_SGD_ACTIVE)
482 return 1;
483 return 0;
484}
485
486static int via_sg_offset(struct via_channel *chan)
487{
488 return inl (chan->iobase + VIA_PCM_BLOCK_COUNT) & 0x00FFFFFF;
489}
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509static inline int via_syscall_down (struct via_info *card, int nonblock)
510{
511
512
513
514
515
516
517 nonblock = 0;
518
519 if (nonblock) {
520 if (down_trylock (&card->syscall_sem))
521 return -EAGAIN;
522 } else {
523 if (down_interruptible (&card->syscall_sem))
524 return -ERESTARTSYS;
525 }
526
527 return 0;
528}
529
530
531
532
533
534
535
536
537
538
539static void via_stop_everything (struct via_info *card)
540{
541 u8 tmp, new_tmp;
542
543 DPRINTK ("ENTER\n");
544
545 assert (card != NULL);
546
547
548
549
550 via_chan_stop (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN);
551 via_chan_stop (card->baseaddr + VIA_BASE0_PCM_IN_CHAN);
552 via_chan_stop (card->baseaddr + VIA_BASE0_FM_OUT_CHAN);
553 if(card->sixchannel)
554 via_chan_stop (card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN);
555
556
557
558
559 via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN);
560 via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_IN_CHAN);
561 via_chan_status_clear (card->baseaddr + VIA_BASE0_FM_OUT_CHAN);
562 if(card->sixchannel)
563 via_chan_status_clear (card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN);
564
565
566
567
568 tmp = inb (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN_TYPE);
569 new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL);
570 if (tmp != new_tmp)
571 outb (0, card->baseaddr + VIA_BASE0_PCM_OUT_CHAN_TYPE);
572
573 tmp = inb (card->baseaddr + VIA_BASE0_PCM_IN_CHAN_TYPE);
574 new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL);
575 if (tmp != new_tmp)
576 outb (0, card->baseaddr + VIA_BASE0_PCM_IN_CHAN_TYPE);
577
578 tmp = inb (card->baseaddr + VIA_BASE0_FM_OUT_CHAN_TYPE);
579 new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL);
580 if (tmp != new_tmp)
581 outb (0, card->baseaddr + VIA_BASE0_FM_OUT_CHAN_TYPE);
582
583 if(card->sixchannel)
584 {
585 tmp = inb (card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN_TYPE);
586 new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL);
587 if (tmp != new_tmp)
588 outb (0, card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN_TYPE);
589 }
590
591 udelay(10);
592
593
594
595
596 via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN);
597 via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_IN_CHAN);
598 via_chan_status_clear (card->baseaddr + VIA_BASE0_FM_OUT_CHAN);
599
600 DPRINTK ("EXIT\n");
601}
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616static int via_set_rate (struct ac97_codec *ac97,
617 struct via_channel *chan, unsigned rate)
618{
619 struct via_info *card = ac97->private_data;
620 int rate_reg;
621 u32 dacp;
622 u32 mast_vol, phone_vol, mono_vol, pcm_vol;
623 u32 mute_vol = 0x8000;
624
625 DPRINTK ("ENTER, rate = %d\n", rate);
626
627 if (chan->rate == rate)
628 goto out;
629 if (card->locked_rate) {
630 chan->rate = 48000;
631 goto out;
632 }
633
634 if (rate > 48000) rate = 48000;
635 if (rate < 4000) rate = 4000;
636
637 rate_reg = chan->is_record ? AC97_PCM_LR_ADC_RATE :
638 AC97_PCM_FRONT_DAC_RATE;
639
640
641 dacp=via_ac97_read_reg(ac97, AC97_POWER_CONTROL);
642 mast_vol = via_ac97_read_reg(ac97, AC97_MASTER_VOL_STEREO);
643 mono_vol = via_ac97_read_reg(ac97, AC97_MASTER_VOL_MONO);
644 phone_vol = via_ac97_read_reg(ac97, AC97_HEADPHONE_VOL);
645 pcm_vol = via_ac97_read_reg(ac97, AC97_PCMOUT_VOL);
646
647 via_ac97_write_reg(ac97, AC97_MASTER_VOL_STEREO, mute_vol);
648 via_ac97_write_reg(ac97, AC97_MASTER_VOL_MONO, mute_vol);
649 via_ac97_write_reg(ac97, AC97_HEADPHONE_VOL, mute_vol);
650 via_ac97_write_reg(ac97, AC97_PCMOUT_VOL, mute_vol);
651
652 via_ac97_write_reg(ac97, AC97_POWER_CONTROL, dacp|0x0200);
653
654
655 via_ac97_write_reg (ac97, rate_reg, rate);
656
657
658 via_ac97_write_reg(ac97, AC97_POWER_CONTROL, dacp);
659 udelay (200);
660
661
662 via_ac97_write_reg(ac97, AC97_MASTER_VOL_STEREO, mast_vol);
663 via_ac97_write_reg(ac97, AC97_MASTER_VOL_MONO, mono_vol);
664 via_ac97_write_reg(ac97, AC97_HEADPHONE_VOL, phone_vol);
665 via_ac97_write_reg(ac97, AC97_PCMOUT_VOL, pcm_vol);
666
667
668
669
670
671 chan->rate = via_ac97_read_reg (ac97, rate_reg);
672
673 if (chan->rate == 0) {
674 card->locked_rate = 1;
675 chan->rate = 48000;
676 printk (KERN_WARNING PFX "Codec rate locked at 48Khz\n");
677 }
678
679out:
680 DPRINTK ("EXIT, returning rate %d Hz\n", chan->rate);
681 return chan->rate;
682}
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701static void via_chan_init_defaults (struct via_info *card, struct via_channel *chan)
702{
703 memset (chan, 0, sizeof (*chan));
704
705 if(card->intmask)
706 chan->intmask = 0x23;
707
708 if (chan == &card->ch_out) {
709 chan->name = "PCM-OUT";
710 if(card->sixchannel)
711 {
712 chan->iobase = card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN;
713 chan->is_multi = 1;
714 DPRINTK("Using multichannel for pcm out\n");
715 }
716 else
717 chan->iobase = card->baseaddr + VIA_BASE0_PCM_OUT_CHAN;
718 } else if (chan == &card->ch_in) {
719 chan->name = "PCM-IN";
720 chan->iobase = card->baseaddr + VIA_BASE0_PCM_IN_CHAN;
721 chan->is_record = 1;
722 } else if (chan == &card->ch_fm) {
723 chan->name = "PCM-OUT-FM";
724 chan->iobase = card->baseaddr + VIA_BASE0_FM_OUT_CHAN;
725 } else {
726 BUG();
727 }
728
729 init_waitqueue_head (&chan->wait);
730
731 chan->pcm_fmt = VIA_PCM_FMT_MASK;
732 chan->is_enabled = 1;
733
734 chan->frag_number = 0;
735 chan->frag_size = 0;
736 atomic_set(&chan->n_frags, 0);
737 atomic_set (&chan->hw_ptr, 0);
738}
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753static void via_chan_init (struct via_info *card, struct via_channel *chan)
754{
755
756 DPRINTK ("ENTER\n");
757
758
759 via_chan_init_defaults (card, chan);
760
761
762 via_chan_clear (card, chan);
763 via_chan_status_clear (chan->iobase);
764 via_chan_pcm_fmt (chan, 1);
765
766 DPRINTK ("EXIT\n");
767}
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788static int via_chan_buffer_init (struct via_info *card, struct via_channel *chan)
789{
790 int page, offset;
791 int i;
792
793 DPRINTK ("ENTER\n");
794
795
796 chan->intmask = 0;
797 if(card->intmask)
798 chan->intmask = 0x23;
799
800 if (chan->sgtable != NULL) {
801 DPRINTK ("EXIT\n");
802 return 0;
803 }
804
805
806 chan->sgtable = pci_alloc_consistent (card->pdev,
807 (sizeof (struct via_sgd_table) * chan->frag_number),
808 &chan->sgt_handle);
809 if (!chan->sgtable) {
810 printk (KERN_ERR PFX "DMA table alloc fail, aborting\n");
811 DPRINTK ("EXIT\n");
812 return -ENOMEM;
813 }
814
815 memset ((void*)chan->sgtable, 0,
816 (sizeof (struct via_sgd_table) * chan->frag_number));
817
818
819
820 chan->page_number = (chan->frag_number * chan->frag_size) / PAGE_SIZE +
821 (((chan->frag_number * chan->frag_size) % PAGE_SIZE) ? 1 : 0);
822
823 for (i = 0; i < chan->page_number; i++) {
824 chan->pgtbl[i].cpuaddr = pci_alloc_consistent (card->pdev, PAGE_SIZE,
825 &chan->pgtbl[i].handle);
826
827 if (!chan->pgtbl[i].cpuaddr) {
828 chan->page_number = i;
829 goto err_out_nomem;
830 }
831
832#ifndef VIA_NDEBUG
833 memset (chan->pgtbl[i].cpuaddr, 0xBC, chan->frag_size);
834#endif
835
836#if 1
837 DPRINTK ("dmabuf_pg #%d (h=%lx, v2p=%lx, a=%p)\n",
838 i, (long)chan->pgtbl[i].handle,
839 virt_to_phys(chan->pgtbl[i].cpuaddr),
840 chan->pgtbl[i].cpuaddr);
841#endif
842 }
843
844 for (i = 0; i < chan->frag_number; i++) {
845
846 page = i / (PAGE_SIZE / chan->frag_size);
847 offset = (i % (PAGE_SIZE / chan->frag_size)) * chan->frag_size;
848
849 chan->sgtable[i].count = cpu_to_le32 (chan->frag_size | VIA_FLAG);
850 chan->sgtable[i].addr = cpu_to_le32 (chan->pgtbl[page].handle + offset);
851
852#if 1
853 DPRINTK ("dmabuf #%d (32(h)=%lx)\n",
854 i,
855 (long)chan->sgtable[i].addr);
856#endif
857 }
858
859
860 chan->sgtable[chan->frag_number - 1].count = cpu_to_le32 (chan->frag_size | VIA_EOL);
861
862
863 DPRINTK ("outl (0x%X, 0x%04lX)\n",
864 chan->sgt_handle, chan->iobase + VIA_PCM_TABLE_ADDR);
865
866 via_ac97_wait_idle (card);
867 outl (chan->sgt_handle, chan->iobase + VIA_PCM_TABLE_ADDR);
868 udelay (20);
869 via_ac97_wait_idle (card);
870
871 if(card->sixchannel)
872 {
873 if(!chan->is_multi)
874 {
875 outl (0xFFFFF | (0x3 << 20) | (chan->frag_number << 24), chan->iobase + VIA_PCM_STOPRATE);
876 udelay (20);
877 via_ac97_wait_idle (card);
878 }
879 }
880
881 DPRINTK ("inl (0x%lX) = %x\n",
882 chan->iobase + VIA_PCM_TABLE_ADDR,
883 inl(chan->iobase + VIA_PCM_TABLE_ADDR));
884
885 DPRINTK ("EXIT\n");
886 return 0;
887
888err_out_nomem:
889 printk (KERN_ERR PFX "DMA buffer alloc fail, aborting\n");
890 via_chan_buffer_free (card, chan);
891 DPRINTK ("EXIT\n");
892 return -ENOMEM;
893}
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910static void via_chan_free (struct via_info *card, struct via_channel *chan)
911{
912 DPRINTK ("ENTER\n");
913
914 spin_lock_irq (&card->lock);
915
916
917 via_chan_status_clear (chan->iobase);
918 via_chan_stop (chan->iobase);
919 via_chan_status_clear (chan->iobase);
920
921 spin_unlock_irq (&card->lock);
922
923 synchronize_irq();
924
925 DPRINTK ("EXIT\n");
926}
927
928static void via_chan_buffer_free (struct via_info *card, struct via_channel *chan)
929{
930 int i;
931
932 DPRINTK ("ENTER\n");
933
934
935 via_ac97_wait_idle(card);
936 outl (0, chan->iobase + VIA_PCM_TABLE_ADDR);
937
938 for (i = 0; i < chan->page_number; i++)
939 if (chan->pgtbl[i].cpuaddr) {
940 pci_free_consistent (card->pdev, PAGE_SIZE,
941 chan->pgtbl[i].cpuaddr,
942 chan->pgtbl[i].handle);
943 chan->pgtbl[i].cpuaddr = NULL;
944 chan->pgtbl[i].handle = 0;
945 }
946
947 chan->page_number = 0;
948
949 if (chan->sgtable) {
950 pci_free_consistent (card->pdev,
951 (sizeof (struct via_sgd_table) * chan->frag_number),
952 (void*)chan->sgtable, chan->sgt_handle);
953 chan->sgtable = NULL;
954 }
955
956 DPRINTK ("EXIT\n");
957}
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975static void via_chan_pcm_fmt (struct via_channel *chan, int reset)
976{
977 DPRINTK ("ENTER, pcm_fmt=0x%02X, reset=%s\n",
978 chan->pcm_fmt, reset ? "yes" : "no");
979
980 assert (chan != NULL);
981
982 if (reset)
983 {
984
985 chan->pcm_fmt = 0;
986 chan->channels = 1;
987 }
988
989
990 chan->pcm_fmt |= VIA_CHAN_TYPE_MASK;
991
992
993 if (chan->is_record)
994 chan->pcm_fmt |= VIA_PCM_REC_FIFO;
995
996 if (!chan->is_record)
997 chan->pcm_fmt |= VIA_CHAN_TYPE_INT_SELECT;
998
999 DPRINTK("SET FMT - %02x %02x\n", chan->intmask , chan->is_multi);
1000
1001 if(chan->intmask)
1002 {
1003 u32 m;
1004
1005
1006
1007
1008
1009
1010 if(chan->is_multi)
1011 {
1012 u8 c = 0;
1013
1014
1015
1016
1017
1018
1019 if(chan->pcm_fmt & VIA_PCM_FMT_16BIT)
1020 c = 1 << 7;
1021 if(chan->pcm_fmt & VIA_PCM_FMT_STEREO)
1022 c |= (2<<4);
1023 else
1024 c |= (1<<4);
1025
1026 outb(c, chan->iobase + VIA_PCM_TYPE);
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038 switch(chan->channels)
1039 {
1040 case 1:
1041 outl(0xFF000000 | (1<<0) | (1<<4) , chan->iobase + VIA_PCM_STOPRATE);
1042 break;
1043 case 2:
1044 outl(0xFF000000 | (1<<0) | (2<<4) , chan->iobase + VIA_PCM_STOPRATE);
1045 break;
1046 case 4:
1047 outl(0xFF000000 | (1<<0) | (2<<4) | (3<<8) | (4<<12), chan->iobase + VIA_PCM_STOPRATE);
1048 break;
1049 case 6:
1050 outl(0xFF000000 | (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20), chan->iobase + VIA_PCM_STOPRATE);
1051 break;
1052 }
1053 }
1054 else
1055 {
1056
1057
1058
1059
1060 outb(0x0, chan->iobase + VIA_PCM_LEFTVOL);
1061 outb(0x0, chan->iobase + VIA_PCM_RIGHTVOL);
1062
1063 m = inl(chan->iobase + VIA_PCM_STOPRATE);
1064 m &= ~(3<<20);
1065 if(chan->pcm_fmt & VIA_PCM_FMT_STEREO)
1066 m |= (1 << 20);
1067 if(chan->pcm_fmt & VIA_PCM_FMT_16BIT)
1068 m |= (1 << 21);
1069 outl(m, chan->iobase + VIA_PCM_STOPRATE);
1070 }
1071 }
1072 else
1073 outb (chan->pcm_fmt, chan->iobase + VIA_PCM_TYPE);
1074
1075
1076 DPRINTK ("EXIT, pcm_fmt = 0x%02X, reg = 0x%02X\n",
1077 chan->pcm_fmt,
1078 inb (chan->iobase + VIA_PCM_TYPE));
1079}
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091static void via_chan_clear (struct via_info *card, struct via_channel *chan)
1092{
1093 DPRINTK ("ENTER\n");
1094 via_chan_stop (chan->iobase);
1095 via_chan_buffer_free(card, chan);
1096 chan->is_active = 0;
1097 chan->is_mapped = 0;
1098 chan->is_enabled = 1;
1099 chan->slop_len = 0;
1100 chan->sw_ptr = 0;
1101 chan->n_irqs = 0;
1102 atomic_set (&chan->hw_ptr, 0);
1103 DPRINTK ("EXIT\n");
1104}
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122static int via_chan_set_speed (struct via_info *card,
1123 struct via_channel *chan, int val)
1124{
1125 DPRINTK ("ENTER, requested rate = %d\n", val);
1126
1127 via_chan_clear (card, chan);
1128
1129 val = via_set_rate (card->ac97, chan, val);
1130
1131 DPRINTK ("EXIT, returning %d\n", val);
1132 return val;
1133}
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151static int via_chan_set_fmt (struct via_info *card,
1152 struct via_channel *chan, int val)
1153{
1154 DPRINTK ("ENTER, val=%s\n",
1155 val == AFMT_U8 ? "AFMT_U8" :
1156 val == AFMT_S16_LE ? "AFMT_S16_LE" :
1157 "unknown");
1158
1159 via_chan_clear (card, chan);
1160
1161 assert (val != AFMT_QUERY);
1162
1163 switch (val) {
1164 case AFMT_S16_LE:
1165 if ((chan->pcm_fmt & VIA_PCM_FMT_16BIT) == 0) {
1166 chan->pcm_fmt |= VIA_PCM_FMT_16BIT;
1167 via_chan_pcm_fmt (chan, 0);
1168 }
1169 break;
1170
1171 case AFMT_U8:
1172 if (chan->pcm_fmt & VIA_PCM_FMT_16BIT) {
1173 chan->pcm_fmt &= ~VIA_PCM_FMT_16BIT;
1174 via_chan_pcm_fmt (chan, 0);
1175 }
1176 break;
1177
1178 default:
1179 DPRINTK ("unknown AFMT: 0x%X\n", val);
1180 val = AFMT_S16_LE;
1181 }
1182
1183 DPRINTK ("EXIT\n");
1184 return val;
1185}
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203static int via_chan_set_stereo (struct via_info *card,
1204 struct via_channel *chan, int val)
1205{
1206 DPRINTK ("ENTER, channels = %d\n", val);
1207
1208 via_chan_clear (card, chan);
1209
1210 switch (val) {
1211
1212
1213 case 1:
1214 chan->pcm_fmt &= ~VIA_PCM_FMT_STEREO;
1215 chan->channels = 1;
1216 via_chan_pcm_fmt (chan, 0);
1217 break;
1218
1219
1220 case 2:
1221 chan->pcm_fmt |= VIA_PCM_FMT_STEREO;
1222 chan->channels = 2;
1223 via_chan_pcm_fmt (chan, 0);
1224 break;
1225
1226 case 4:
1227 case 6:
1228 if(chan->is_multi)
1229 {
1230 chan->pcm_fmt |= VIA_PCM_FMT_STEREO;
1231 chan->channels = val;
1232 break;
1233 }
1234
1235 default:
1236 val = -EINVAL;
1237 break;
1238 }
1239
1240 DPRINTK ("EXIT, returning %d\n", val);
1241 return val;
1242}
1243
1244static int via_chan_set_buffering (struct via_info *card,
1245 struct via_channel *chan, int val)
1246{
1247 int shift;
1248
1249 DPRINTK ("ENTER\n");
1250
1251
1252 if (chan->is_active || chan->is_mapped) {
1253 DPRINTK ("EXIT\n");
1254 return -EINVAL;
1255 }
1256
1257
1258
1259 if (val < 0) {
1260
1261 if (chan->frag_size && chan->frag_number)
1262 goto out;
1263
1264 DPRINTK ("\n");
1265
1266 chan->frag_size = (VIA_DEFAULT_FRAG_TIME * chan->rate * chan->channels
1267 * ((chan->pcm_fmt & VIA_PCM_FMT_16BIT) ? 2 : 1)) / 1000 - 1;
1268
1269 shift = 0;
1270 while (chan->frag_size) {
1271 chan->frag_size >>= 1;
1272 shift++;
1273 }
1274 chan->frag_size = 1 << shift;
1275
1276 chan->frag_number = (VIA_DEFAULT_BUFFER_TIME / VIA_DEFAULT_FRAG_TIME);
1277
1278 DPRINTK ("setting default values %d %d\n", chan->frag_size, chan->frag_number);
1279 } else {
1280 chan->frag_size = 1 << (val & 0xFFFF);
1281 chan->frag_number = (val >> 16) & 0xFFFF;
1282
1283 DPRINTK ("using user values %d %d\n", chan->frag_size, chan->frag_number);
1284 }
1285
1286
1287 shift = 0;
1288 while (chan->frag_number) {
1289 chan->frag_number >>= 1;
1290 shift++;
1291 }
1292 chan->frag_number = 1 << shift;
1293
1294 if (chan->frag_size > VIA_MAX_FRAG_SIZE)
1295 chan->frag_size = VIA_MAX_FRAG_SIZE;
1296 else if (chan->frag_size < VIA_MIN_FRAG_SIZE)
1297 chan->frag_size = VIA_MIN_FRAG_SIZE;
1298
1299 if (chan->frag_number < VIA_MIN_FRAG_NUMBER)
1300 chan->frag_number = VIA_MIN_FRAG_NUMBER;
1301 if (chan->frag_number > VIA_MAX_FRAG_NUMBER)
1302 chan->frag_number = VIA_MAX_FRAG_NUMBER;
1303
1304 if ((chan->frag_number * chan->frag_size) / PAGE_SIZE > VIA_MAX_BUFFER_DMA_PAGES)
1305 chan->frag_number = (VIA_MAX_BUFFER_DMA_PAGES * PAGE_SIZE) / chan->frag_size;
1306
1307out:
1308 if (chan->is_record)
1309 atomic_set (&chan->n_frags, 0);
1310 else
1311 atomic_set (&chan->n_frags, chan->frag_number);
1312
1313 DPRINTK ("EXIT\n");
1314
1315 return 0;
1316}
1317
1318#ifdef VIA_CHAN_DUMP_BUFS
1319
1320
1321
1322
1323
1324
1325
1326
1327static void via_chan_dump_bufs (struct via_channel *chan)
1328{
1329 int i;
1330
1331 for (i = 0; i < chan->frag_number; i++) {
1332 DPRINTK ("#%02d: addr=%x, count=%u, flag=%d, eol=%d\n",
1333 i, chan->sgtable[i].addr,
1334 chan->sgtable[i].count & 0x00FFFFFF,
1335 chan->sgtable[i].count & VIA_FLAG ? 1 : 0,
1336 chan->sgtable[i].count & VIA_EOL ? 1 : 0);
1337 }
1338 DPRINTK ("buf_in_use = %d, nextbuf = %d\n",
1339 atomic_read (&chan->buf_in_use),
1340 atomic_read (&chan->sw_ptr));
1341}
1342#endif
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352static void via_chan_flush_frag (struct via_channel *chan)
1353{
1354 DPRINTK ("ENTER\n");
1355
1356 assert (chan->slop_len > 0);
1357
1358 if (chan->sw_ptr == (chan->frag_number - 1))
1359 chan->sw_ptr = 0;
1360 else
1361 chan->sw_ptr++;
1362
1363 chan->slop_len = 0;
1364
1365 assert (atomic_read (&chan->n_frags) > 0);
1366 atomic_dec (&chan->n_frags);
1367
1368 DPRINTK ("EXIT\n");
1369}
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381static inline void via_chan_maybe_start (struct via_channel *chan)
1382{
1383 assert (chan->is_active == sg_active(chan->iobase));
1384
1385 DPRINTK ("MAYBE START %s\n", chan->name);
1386 if (!chan->is_active && chan->is_enabled) {
1387 chan->is_active = 1;
1388 sg_begin (chan);
1389 DPRINTK ("starting channel %s\n", chan->name);
1390 }
1391}
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410static u8 via_ac97_wait_idle (struct via_info *card)
1411{
1412 u8 tmp8;
1413 int counter = VIA_COUNTER_LIMIT;
1414
1415 DPRINTK ("ENTER/EXIT\n");
1416
1417 assert (card != NULL);
1418 assert (card->pdev != NULL);
1419
1420 do {
1421 udelay (15);
1422
1423 tmp8 = inb (card->baseaddr + 0x83);
1424 } while ((tmp8 & VIA_CR83_BUSY) && (counter-- > 0));
1425
1426 if (tmp8 & VIA_CR83_BUSY)
1427 printk (KERN_WARNING PFX "timeout waiting on AC97 codec\n");
1428 return tmp8;
1429}
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg)
1448{
1449 unsigned long data;
1450 struct via_info *card;
1451 int counter;
1452
1453 DPRINTK ("ENTER\n");
1454
1455 assert (codec != NULL);
1456 assert (codec->private_data != NULL);
1457
1458 card = codec->private_data;
1459
1460 spin_lock(&card->ac97_lock);
1461
1462
1463
1464
1465 data = (reg << 16) | VIA_CR80_READ | VIA_CR80_VALID;
1466
1467 outl (data, card->baseaddr + VIA_BASE0_AC97_CTRL);
1468 udelay (20);
1469
1470 for (counter = VIA_COUNTER_LIMIT; counter > 0; counter--) {
1471 udelay (1);
1472 if ((((data = inl(card->baseaddr + VIA_BASE0_AC97_CTRL)) &
1473 (VIA_CR80_VALID|VIA_CR80_BUSY)) == VIA_CR80_VALID))
1474 goto out;
1475 }
1476
1477 printk (KERN_WARNING PFX "timeout while reading AC97 codec (0x%lX)\n", data);
1478 goto err_out;
1479
1480out:
1481
1482
1483 udelay(25);
1484 data = (unsigned long) inl (card->baseaddr + VIA_BASE0_AC97_CTRL);
1485
1486 outb (0x02, card->baseaddr + 0x83);
1487
1488 if (((data & 0x007F0000) >> 16) == reg) {
1489 DPRINTK ("EXIT, success, data=0x%lx, retval=0x%lx\n",
1490 data, data & 0x0000FFFF);
1491 spin_unlock(&card->ac97_lock);
1492 return data & 0x0000FFFF;
1493 }
1494
1495 printk (KERN_WARNING "via82cxxx_audio: not our index: reg=0x%x, newreg=0x%lx\n",
1496 reg, ((data & 0x007F0000) >> 16));
1497
1498err_out:
1499 spin_unlock(&card->ac97_lock);
1500 DPRINTK ("EXIT, returning 0\n");
1501 return 0;
1502}
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value)
1519{
1520 u32 data;
1521 struct via_info *card;
1522 int counter;
1523
1524 DPRINTK ("ENTER\n");
1525
1526 assert (codec != NULL);
1527 assert (codec->private_data != NULL);
1528
1529 card = codec->private_data;
1530
1531 spin_lock(&card->ac97_lock);
1532
1533 data = (reg << 16) + value;
1534 outl (data, card->baseaddr + VIA_BASE0_AC97_CTRL);
1535 udelay (10);
1536
1537 for (counter = VIA_COUNTER_LIMIT; counter > 0; counter--) {
1538 if ((inb (card->baseaddr + 0x83) & VIA_CR83_BUSY) == 0)
1539 goto out;
1540
1541 udelay (15);
1542 }
1543
1544 printk (KERN_WARNING PFX "timeout after AC97 codec write (0x%X, 0x%X)\n", reg, value);
1545
1546out:
1547 spin_unlock(&card->ac97_lock);
1548 DPRINTK ("EXIT\n");
1549}
1550
1551
1552static int via_mixer_open (struct inode *inode, struct file *file)
1553{
1554 int minor = MINOR(inode->i_rdev);
1555 struct via_info *card;
1556 struct pci_dev *pdev;
1557 struct pci_driver *drvr;
1558
1559 DPRINTK ("ENTER\n");
1560
1561 pci_for_each_dev(pdev) {
1562 drvr = pci_dev_driver (pdev);
1563 if (drvr == &via_driver) {
1564 assert (pci_get_drvdata (pdev) != NULL);
1565
1566 card = pci_get_drvdata (pdev);
1567 if (card->ac97->dev_mixer == minor)
1568 goto match;
1569 }
1570 }
1571
1572 DPRINTK ("EXIT, returning -ENODEV\n");
1573 return -ENODEV;
1574
1575match:
1576 file->private_data = card->ac97;
1577
1578 DPRINTK ("EXIT, returning 0\n");
1579 return 0;
1580}
1581
1582static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
1583 unsigned long arg)
1584{
1585 struct ac97_codec *codec = file->private_data;
1586 struct via_info *card;
1587 int nonblock = (file->f_flags & O_NONBLOCK);
1588 int rc;
1589
1590 DPRINTK ("ENTER\n");
1591
1592 assert (codec != NULL);
1593 card = codec->private_data;
1594 assert (card != NULL);
1595
1596 rc = via_syscall_down (card, nonblock);
1597 if (rc) goto out;
1598
1599#if 0
1600
1601
1602
1603 if(card->volume)
1604 {
1605 switch(cmd)
1606 {
1607 case SOUND_MIXER_READ_VOLUME:
1608 return card->mixer_vol;
1609 case SOUND_MIXER_WRITE_VOLUME:
1610 {
1611 int v;
1612 if(get_user(v, (int *)arg))
1613 {
1614 rc = -EFAULT;
1615 goto out;
1616 }
1617 card->mixer_vol = v;
1618 }
1619 }
1620 }
1621#endif
1622 rc = codec->mixer_ioctl(codec, cmd, arg);
1623
1624 up (&card->syscall_sem);
1625
1626out:
1627 DPRINTK ("EXIT, returning %d\n", rc);
1628 return rc;
1629}
1630
1631
1632static struct file_operations via_mixer_fops = {
1633 owner: THIS_MODULE,
1634 open: via_mixer_open,
1635 llseek: no_llseek,
1636 ioctl: via_mixer_ioctl,
1637};
1638
1639
1640static int __init via_ac97_reset (struct via_info *card)
1641{
1642 struct pci_dev *pdev = card->pdev;
1643 u8 tmp8;
1644 u16 tmp16;
1645
1646 DPRINTK ("ENTER\n");
1647
1648 assert (pdev != NULL);
1649
1650#ifndef NDEBUG
1651 {
1652 u8 r40,r41,r42,r43,r44,r48;
1653 pci_read_config_byte (card->pdev, 0x40, &r40);
1654 pci_read_config_byte (card->pdev, 0x41, &r41);
1655 pci_read_config_byte (card->pdev, 0x42, &r42);
1656 pci_read_config_byte (card->pdev, 0x43, &r43);
1657 pci_read_config_byte (card->pdev, 0x44, &r44);
1658 pci_read_config_byte (card->pdev, 0x48, &r48);
1659 DPRINTK ("PCI config: %02X %02X %02X %02X %02X %02X\n",
1660 r40,r41,r42,r43,r44,r48);
1661
1662 spin_lock_irq (&card->lock);
1663 DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n",
1664 inb (card->baseaddr + 0x00),
1665 inb (card->baseaddr + 0x01),
1666 inb (card->baseaddr + 0x02),
1667 inl (card->baseaddr + 0x04),
1668 inl (card->baseaddr + 0x0C),
1669 inl (card->baseaddr + 0x80),
1670 inl (card->baseaddr + 0x84));
1671 spin_unlock_irq (&card->lock);
1672
1673 }
1674#endif
1675
1676
1677
1678
1679
1680
1681
1682 pci_read_config_byte (pdev, VIA_ACLINK_STATUS, &tmp8);
1683 if ((tmp8 & VIA_CR40_AC97_READY) == 0) {
1684 pci_write_config_byte (pdev, VIA_ACLINK_CTRL,
1685 VIA_CR41_AC97_ENABLE |
1686 VIA_CR41_AC97_RESET |
1687 VIA_CR41_AC97_WAKEUP);
1688 udelay (100);
1689
1690 pci_write_config_byte (pdev, VIA_ACLINK_CTRL, 0);
1691 udelay (100);
1692
1693 pci_write_config_byte (pdev, VIA_ACLINK_CTRL,
1694 VIA_CR41_AC97_ENABLE |
1695 VIA_CR41_PCM_ENABLE |
1696 VIA_CR41_VRA | VIA_CR41_AC97_RESET);
1697 udelay (100);
1698 }
1699
1700
1701
1702
1703 pci_read_config_byte (pdev, VIA_ACLINK_CTRL, &tmp8);
1704 if (((tmp8 & VIA_CR41_VRA) == 0) ||
1705 ((tmp8 & VIA_CR41_AC97_ENABLE) == 0) ||
1706 ((tmp8 & VIA_CR41_PCM_ENABLE) == 0) ||
1707 ((tmp8 & VIA_CR41_AC97_RESET) == 0)) {
1708 pci_write_config_byte (pdev, VIA_ACLINK_CTRL,
1709 VIA_CR41_AC97_ENABLE |
1710 VIA_CR41_PCM_ENABLE |
1711 VIA_CR41_VRA | VIA_CR41_AC97_RESET);
1712 udelay (100);
1713 }
1714
1715 if(card->legacy)
1716 {
1717#if 0
1718
1719 pci_write_config_byte (pdev, 0x42, 0x00);
1720 udelay(10);
1721#endif
1722
1723
1724 pci_write_config_byte (pdev, 0x48, 0x05);
1725 udelay(10);
1726 }
1727
1728
1729 outl (0, pci_resource_start (pdev, 0) + 0x8C);
1730
1731
1732
1733
1734 tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
1735 if ((tmp16 & 1) == 0)
1736 via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
1737
1738 DPRINTK ("EXIT, returning 0\n");
1739 return 0;
1740}
1741
1742
1743static void via_ac97_codec_wait (struct ac97_codec *codec)
1744{
1745 assert (codec->private_data != NULL);
1746 via_ac97_wait_idle (codec->private_data);
1747}
1748
1749
1750static int __init via_ac97_init (struct via_info *card)
1751{
1752 int rc;
1753 u16 tmp16;
1754
1755 DPRINTK ("ENTER\n");
1756
1757 assert (card != NULL);
1758
1759 card->ac97 = ac97_alloc_codec();
1760 if(card->ac97 == NULL)
1761 return -ENOMEM;
1762
1763 card->ac97->private_data = card;
1764 card->ac97->codec_read = via_ac97_read_reg;
1765 card->ac97->codec_write = via_ac97_write_reg;
1766 card->ac97->codec_wait = via_ac97_codec_wait;
1767
1768 card->ac97->dev_mixer = register_sound_mixer (&via_mixer_fops, -1);
1769 if (card->ac97->dev_mixer < 0) {
1770 printk (KERN_ERR PFX "unable to register AC97 mixer, aborting\n");
1771 DPRINTK ("EXIT, returning -EIO\n");
1772 ac97_release_codec(card->ac97);
1773 return -EIO;
1774 }
1775
1776 rc = via_ac97_reset (card);
1777 if (rc) {
1778 printk (KERN_ERR PFX "unable to reset AC97 codec, aborting\n");
1779 goto err_out;
1780 }
1781
1782 mdelay(10);
1783
1784 if (ac97_probe_codec (card->ac97) == 0) {
1785 printk (KERN_ERR PFX "unable to probe AC97 codec, aborting\n");
1786 rc = -EIO;
1787 goto err_out;
1788 }
1789
1790
1791 tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
1792 via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
1793
1794
1795
1796
1797
1798 tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
1799 if ((tmp16 & 1) == 0) {
1800 via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1);
1801 tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS);
1802 if ((tmp16 & 1) == 0) {
1803 card->locked_rate = 1;
1804 printk (KERN_WARNING PFX "Codec rate locked at 48Khz\n");
1805 }
1806 }
1807
1808 DPRINTK ("EXIT, returning 0\n");
1809 return 0;
1810
1811err_out:
1812 unregister_sound_mixer (card->ac97->dev_mixer);
1813 DPRINTK ("EXIT, returning %d\n", rc);
1814 ac97_release_codec(card->ac97);
1815 return rc;
1816}
1817
1818
1819static void via_ac97_cleanup (struct via_info *card)
1820{
1821 DPRINTK ("ENTER\n");
1822
1823 assert (card != NULL);
1824 assert (card->ac97->dev_mixer >= 0);
1825
1826 unregister_sound_mixer (card->ac97->dev_mixer);
1827 ac97_release_codec(card->ac97);
1828
1829 DPRINTK ("EXIT\n");
1830}
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852static void via_intr_channel (struct via_info *card, struct via_channel *chan)
1853{
1854 u8 status;
1855 int n;
1856
1857
1858 status = inb (chan->iobase) & (VIA_SGD_FLAG | VIA_SGD_EOL | VIA_SGD_STOPPED);
1859 if (!status)
1860 return;
1861
1862
1863 outb (status, chan->iobase);
1864
1865 if (!chan->sgtable)
1866 return;
1867
1868
1869 n = atomic_read (&chan->hw_ptr);
1870
1871
1872 assert (n >= 0);
1873 assert (n < chan->frag_number);
1874
1875
1876
1877
1878
1879 if (n == (chan->frag_number - 1)) {
1880 chan->sgtable[n].count = cpu_to_le32(chan->frag_size | VIA_EOL);
1881 atomic_set (&chan->hw_ptr, 0);
1882 } else {
1883 chan->sgtable[n].count = cpu_to_le32(chan->frag_size | VIA_FLAG);
1884 atomic_inc (&chan->hw_ptr);
1885 }
1886
1887
1888 chan->n_irqs++;
1889 chan->bytes += chan->frag_size;
1890
1891 if (chan->bytes < 0)
1892 chan->bytes = chan->frag_size;
1893
1894 if (!chan->is_mapped)
1895 {
1896
1897
1898
1899
1900
1901
1902
1903
1904 if (atomic_read (&chan->n_frags) < chan->frag_number)
1905 atomic_inc (&chan->n_frags);
1906 assert (atomic_read (&chan->n_frags) <= chan->frag_number);
1907 if (atomic_read (&chan->n_frags) == chan->frag_number) {
1908 chan->is_active = 0;
1909 via_chan_stop (chan->iobase);
1910 }
1911 }
1912
1913 wake_up_all (&chan->wait);
1914
1915 DPRINTK ("%s intr, status=0x%02X, hwptr=0x%lX, chan->hw_ptr=%d\n",
1916 chan->name, status, (long) inl (chan->iobase + 0x04),
1917 atomic_read (&chan->hw_ptr));
1918
1919 DPRINTK ("%s intr, channel n_frags == %d, missed %d\n", chan->name,
1920 atomic_read (&chan->n_frags), missed);
1921}
1922
1923
1924static void via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1925{
1926 struct via_info *card = dev_id;
1927 u32 status32;
1928
1929
1930
1931
1932
1933
1934 status32 = inl (card->baseaddr + VIA_BASE0_SGD_STATUS_SHADOW);
1935 if (!(status32 & VIA_INTR_MASK))
1936 {
1937#ifdef CONFIG_MIDI_VIA82CXXX
1938 if (card->midi_devc)
1939 uart401intr(irq, card->midi_devc, regs);
1940#endif
1941 return;
1942 }
1943 DPRINTK ("intr, status32 == 0x%08X\n", status32);
1944
1945
1946
1947
1948 spin_lock (&card->lock);
1949
1950 if (status32 & VIA_INTR_OUT)
1951 via_intr_channel (card, &card->ch_out);
1952 if (status32 & VIA_INTR_IN)
1953 via_intr_channel (card, &card->ch_in);
1954 if (status32 & VIA_INTR_FM)
1955 via_intr_channel (card, &card->ch_fm);
1956
1957 spin_unlock (&card->lock);
1958}
1959
1960static void via_new_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1961{
1962 struct via_info *card = dev_id;
1963 u32 status32;
1964
1965
1966
1967
1968
1969
1970 status32 = inl (card->baseaddr + VIA_BASE0_SGD_STATUS_SHADOW);
1971 if (!(status32 & VIA_NEW_INTR_MASK))
1972 return;
1973
1974
1975
1976 spin_lock (&card->lock);
1977
1978 via_intr_channel (card, &card->ch_out);
1979 via_intr_channel (card, &card->ch_in);
1980 via_intr_channel (card, &card->ch_fm);
1981
1982 spin_unlock (&card->lock);
1983}
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995static int via_interrupt_init (struct via_info *card)
1996{
1997 u8 tmp8;
1998
1999 DPRINTK ("ENTER\n");
2000
2001 assert (card != NULL);
2002 assert (card->pdev != NULL);
2003
2004
2005 if (card->pdev->irq < 2) {
2006 printk (KERN_ERR PFX "insane IRQ %d, aborting\n",
2007 card->pdev->irq);
2008 DPRINTK ("EXIT, returning -EIO\n");
2009 return -EIO;
2010 }
2011
2012
2013 pci_write_config_byte(card->pdev, PCI_INTERRUPT_LINE, card->pdev->irq);
2014
2015 if(card->legacy)
2016 {
2017
2018 pci_read_config_byte (card->pdev, VIA_FM_NMI_CTRL, &tmp8);
2019 if ((tmp8 & VIA_CR48_FM_TRAP_TO_NMI) == 0) {
2020 tmp8 |= VIA_CR48_FM_TRAP_TO_NMI;
2021 pci_write_config_byte (card->pdev, VIA_FM_NMI_CTRL, tmp8);
2022 }
2023 if (request_irq (card->pdev->irq, via_interrupt, SA_SHIRQ, VIA_MODULE_NAME, card)) {
2024 printk (KERN_ERR PFX "unable to obtain IRQ %d, aborting\n",
2025 card->pdev->irq);
2026 DPRINTK ("EXIT, returning -EBUSY\n");
2027 return -EBUSY;
2028 }
2029 }
2030 else
2031 {
2032 if (request_irq (card->pdev->irq, via_new_interrupt, SA_SHIRQ, VIA_MODULE_NAME, card)) {
2033 printk (KERN_ERR PFX "unable to obtain IRQ %d, aborting\n",
2034 card->pdev->irq);
2035 DPRINTK ("EXIT, returning -EBUSY\n");
2036 return -EBUSY;
2037 }
2038 }
2039
2040 DPRINTK ("EXIT, returning 0\n");
2041 return 0;
2042}
2043
2044
2045
2046
2047
2048
2049
2050
2051static struct file_operations via_dsp_fops = {
2052 owner: THIS_MODULE,
2053 open: via_dsp_open,
2054 release: via_dsp_release,
2055 read: via_dsp_read,
2056 write: via_dsp_write,
2057 poll: via_dsp_poll,
2058 llseek: no_llseek,
2059 ioctl: via_dsp_ioctl,
2060 mmap: via_dsp_mmap,
2061};
2062
2063
2064static int __init via_dsp_init (struct via_info *card)
2065{
2066 u8 tmp8;
2067
2068 DPRINTK ("ENTER\n");
2069
2070 assert (card != NULL);
2071
2072 if(card->legacy)
2073 {
2074
2075 pci_read_config_byte (card->pdev, VIA_FUNC_ENABLE, &tmp8);
2076 if (tmp8 & (VIA_CR42_SB_ENABLE | VIA_CR42_FM_ENABLE)) {
2077 tmp8 &= ~(VIA_CR42_SB_ENABLE | VIA_CR42_FM_ENABLE);
2078 pci_write_config_byte (card->pdev, VIA_FUNC_ENABLE, tmp8);
2079 }
2080 }
2081
2082 via_stop_everything (card);
2083
2084 card->dev_dsp = register_sound_dsp (&via_dsp_fops, -1);
2085 if (card->dev_dsp < 0) {
2086 DPRINTK ("EXIT, returning -ENODEV\n");
2087 return -ENODEV;
2088 }
2089 DPRINTK ("EXIT, returning 0\n");
2090 return 0;
2091}
2092
2093
2094static void via_dsp_cleanup (struct via_info *card)
2095{
2096 DPRINTK ("ENTER\n");
2097
2098 assert (card != NULL);
2099 assert (card->dev_dsp >= 0);
2100
2101 via_stop_everything (card);
2102
2103 unregister_sound_dsp (card->dev_dsp);
2104
2105 DPRINTK ("EXIT\n");
2106}
2107
2108
2109static struct page * via_mm_nopage (struct vm_area_struct * vma,
2110 unsigned long address, int write_access)
2111{
2112 struct via_info *card = vma->vm_private_data;
2113 struct via_channel *chan = &card->ch_out;
2114 struct page *dmapage;
2115 unsigned long pgoff;
2116 int rd, wr;
2117
2118 DPRINTK ("ENTER, start %lXh, ofs %lXh, pgoff %ld, addr %lXh, wr %d\n",
2119 vma->vm_start,
2120 address - vma->vm_start,
2121 (address - vma->vm_start) >> PAGE_SHIFT,
2122 address,
2123 write_access);
2124
2125 if (address > vma->vm_end) {
2126 DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n");
2127 return NOPAGE_SIGBUS;
2128 }
2129 if (!card) {
2130 DPRINTK ("EXIT, returning NOPAGE_OOM\n");
2131 return NOPAGE_OOM;
2132 }
2133
2134 pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT);
2135 rd = card->ch_in.is_mapped;
2136 wr = card->ch_out.is_mapped;
2137
2138#ifndef VIA_NDEBUG
2139 {
2140 unsigned long max_bufs = chan->frag_number;
2141 if (rd && wr) max_bufs *= 2;
2142
2143 assert (pgoff < max_bufs);
2144 }
2145#endif
2146
2147
2148
2149 if (pgoff >= chan->page_number) {
2150 pgoff -= chan->page_number;
2151 chan = &card->ch_in;
2152 } else if (!wr)
2153 chan = &card->ch_in;
2154
2155 assert ((((unsigned long)chan->pgtbl[pgoff].cpuaddr) % PAGE_SIZE) == 0);
2156
2157 dmapage = virt_to_page (chan->pgtbl[pgoff].cpuaddr);
2158 DPRINTK ("EXIT, returning page %p for cpuaddr %lXh\n",
2159 dmapage, (unsigned long) chan->pgtbl[pgoff].cpuaddr);
2160 get_page (dmapage);
2161 return dmapage;
2162}
2163
2164
2165#ifndef VM_RESERVED
2166static int via_mm_swapout (struct page *page, struct file *filp)
2167{
2168 return 0;
2169}
2170#endif
2171
2172
2173struct vm_operations_struct via_mm_ops = {
2174 nopage: via_mm_nopage,
2175
2176#ifndef VM_RESERVED
2177 swapout: via_mm_swapout,
2178#endif
2179};
2180
2181
2182static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma)
2183{
2184 struct via_info *card;
2185 int nonblock = (file->f_flags & O_NONBLOCK);
2186 int rc = -EINVAL, rd=0, wr=0;
2187 unsigned long max_size, size, start, offset;
2188
2189 assert (file != NULL);
2190 assert (vma != NULL);
2191 card = file->private_data;
2192 assert (card != NULL);
2193
2194 DPRINTK ("ENTER, start %lXh, size %ld, pgoff %ld\n",
2195 vma->vm_start,
2196 vma->vm_end - vma->vm_start,
2197 vma->vm_pgoff);
2198
2199 max_size = 0;
2200 if (vma->vm_flags & VM_READ) {
2201 rd = 1;
2202 via_chan_set_buffering(card, &card->ch_in, -1);
2203 via_chan_buffer_init (card, &card->ch_in);
2204 max_size += card->ch_in.page_number << PAGE_SHIFT;
2205 }
2206 if (vma->vm_flags & VM_WRITE) {
2207 wr = 1;
2208 via_chan_set_buffering(card, &card->ch_out, -1);
2209 via_chan_buffer_init (card, &card->ch_out);
2210 max_size += card->ch_out.page_number << PAGE_SHIFT;
2211 }
2212
2213 start = vma->vm_start;
2214 offset = (vma->vm_pgoff << PAGE_SHIFT);
2215 size = vma->vm_end - vma->vm_start;
2216
2217
2218 if (size > max_size)
2219 goto out;
2220 if (offset > max_size - size)
2221 goto out;
2222
2223 rc = via_syscall_down (card, nonblock);
2224 if (rc) goto out;
2225
2226 vma->vm_ops = &via_mm_ops;
2227 vma->vm_private_data = card;
2228
2229#ifdef VM_RESERVED
2230 vma->vm_flags |= VM_RESERVED;
2231#endif
2232
2233 if (rd)
2234 card->ch_in.is_mapped = 1;
2235 if (wr)
2236 card->ch_out.is_mapped = 1;
2237
2238 up (&card->syscall_sem);
2239 rc = 0;
2240
2241out:
2242 DPRINTK ("EXIT, returning %d\n", rc);
2243 return rc;
2244}
2245
2246
2247static ssize_t via_dsp_do_read (struct via_info *card,
2248 char *userbuf, size_t count,
2249 int nonblock)
2250{
2251 DECLARE_WAITQUEUE(wait, current);
2252 const char *orig_userbuf = userbuf;
2253 struct via_channel *chan = &card->ch_in;
2254 size_t size;
2255 int n, tmp;
2256 ssize_t ret = 0;
2257
2258
2259 via_chan_maybe_start (chan);
2260
2261handle_one_block:
2262
2263
2264
2265 if (current->need_resched) {
2266 up(&card->syscall_sem);
2267 schedule ();
2268 ret = via_syscall_down (card, nonblock);
2269 if (ret)
2270 goto out;
2271 }
2272
2273
2274
2275
2276
2277 n = chan->sw_ptr;
2278
2279
2280
2281
2282
2283 add_wait_queue(&chan->wait, &wait);
2284 for (;;) {
2285 __set_current_state(TASK_INTERRUPTIBLE);
2286 tmp = atomic_read (&chan->n_frags);
2287 assert (tmp >= 0);
2288 assert (tmp <= chan->frag_number);
2289 if (tmp)
2290 break;
2291 if (nonblock || !chan->is_active) {
2292 ret = -EAGAIN;
2293 break;
2294 }
2295
2296 up(&card->syscall_sem);
2297
2298 DPRINTK ("Sleeping on block %d\n", n);
2299 schedule();
2300
2301 ret = via_syscall_down (card, nonblock);
2302 if (ret)
2303 break;
2304
2305 if (signal_pending (current)) {
2306 ret = -ERESTARTSYS;
2307 break;
2308 }
2309 }
2310 set_current_state(TASK_RUNNING);
2311 remove_wait_queue(&chan->wait, &wait);
2312 if (ret)
2313 goto out;
2314
2315
2316
2317
2318 while ((count > 0) && (chan->slop_len < chan->frag_size)) {
2319 size_t slop_left = chan->frag_size - chan->slop_len;
2320 void *base = chan->pgtbl[n / (PAGE_SIZE / chan->frag_size)].cpuaddr;
2321 unsigned ofs = (n % (PAGE_SIZE / chan->frag_size)) * chan->frag_size;
2322
2323 size = (count < slop_left) ? count : slop_left;
2324 if (copy_to_user (userbuf,
2325 base + ofs + chan->slop_len,
2326 size)) {
2327 ret = -EFAULT;
2328 goto out;
2329 }
2330
2331 count -= size;
2332 chan->slop_len += size;
2333 userbuf += size;
2334 }
2335
2336
2337
2338
2339 if (chan->slop_len < chan->frag_size)
2340 goto out;
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350 if (chan->sw_ptr == (chan->frag_number - 1))
2351 chan->sw_ptr = 0;
2352 else
2353 chan->sw_ptr++;
2354
2355
2356 assert (atomic_read (&chan->n_frags) > 0);
2357 atomic_dec (&chan->n_frags);
2358
2359
2360 chan->slop_len = 0;
2361
2362 DPRINTK ("Flushed block %u, sw_ptr now %u, n_frags now %d\n",
2363 n, chan->sw_ptr, atomic_read (&chan->n_frags));
2364
2365 DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n",
2366 inb (card->baseaddr + 0x00),
2367 inb (card->baseaddr + 0x01),
2368 inb (card->baseaddr + 0x02),
2369 inl (card->baseaddr + 0x04),
2370 inl (card->baseaddr + 0x0C),
2371 inl (card->baseaddr + 0x80),
2372 inl (card->baseaddr + 0x84));
2373
2374 if (count > 0)
2375 goto handle_one_block;
2376
2377out:
2378 return (userbuf != orig_userbuf) ? (userbuf - orig_userbuf) : ret;
2379}
2380
2381
2382static ssize_t via_dsp_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
2383{
2384 struct via_info *card;
2385 int nonblock = (file->f_flags & O_NONBLOCK);
2386 int rc;
2387
2388 DPRINTK ("ENTER, file=%p, buffer=%p, count=%u, ppos=%lu\n",
2389 file, buffer, count, ppos ? ((unsigned long)*ppos) : 0);
2390
2391 assert (file != NULL);
2392 card = file->private_data;
2393 assert (card != NULL);
2394
2395 if (ppos != &file->f_pos) {
2396 DPRINTK ("EXIT, returning -ESPIPE\n");
2397 return -ESPIPE;
2398 }
2399
2400 rc = via_syscall_down (card, nonblock);
2401 if (rc) goto out;
2402
2403 if (card->ch_in.is_mapped) {
2404 rc = -ENXIO;
2405 goto out_up;
2406 }
2407
2408 via_chan_set_buffering(card, &card->ch_in, -1);
2409 rc = via_chan_buffer_init (card, &card->ch_in);
2410
2411 if (rc)
2412 goto out_up;
2413
2414 rc = via_dsp_do_read (card, buffer, count, nonblock);
2415
2416out_up:
2417 up (&card->syscall_sem);
2418out:
2419 DPRINTK ("EXIT, returning %ld\n",(long) rc);
2420 return rc;
2421}
2422
2423
2424static ssize_t via_dsp_do_write (struct via_info *card,
2425 const char *userbuf, size_t count,
2426 int nonblock)
2427{
2428 DECLARE_WAITQUEUE(wait, current);
2429 const char *orig_userbuf = userbuf;
2430 struct via_channel *chan = &card->ch_out;
2431 volatile struct via_sgd_table *sgtable = chan->sgtable;
2432 size_t size;
2433 int n, tmp;
2434 ssize_t ret = 0;
2435
2436handle_one_block:
2437
2438
2439
2440 if (current->need_resched) {
2441 up(&card->syscall_sem);
2442 schedule ();
2443 ret = via_syscall_down (card, nonblock);
2444 if (ret)
2445 goto out;
2446 }
2447
2448
2449
2450
2451
2452 n = chan->sw_ptr;
2453
2454
2455
2456
2457
2458 add_wait_queue(&chan->wait, &wait);
2459 for (;;) {
2460 __set_current_state(TASK_INTERRUPTIBLE);
2461 tmp = atomic_read (&chan->n_frags);
2462 assert (tmp >= 0);
2463 assert (tmp <= chan->frag_number);
2464 if (tmp)
2465 break;
2466 if (nonblock || !chan->is_active) {
2467 ret = -EAGAIN;
2468 break;
2469 }
2470
2471 up(&card->syscall_sem);
2472
2473 DPRINTK ("Sleeping on page %d, tmp==%d, ir==%d\n", n, tmp, chan->is_record);
2474 schedule();
2475
2476 ret = via_syscall_down (card, nonblock);
2477 if (ret)
2478 break;
2479
2480 if (signal_pending (current)) {
2481 ret = -ERESTARTSYS;
2482 break;
2483 }
2484 }
2485 set_current_state(TASK_RUNNING);
2486 remove_wait_queue(&chan->wait, &wait);
2487 if (ret)
2488 goto out;
2489
2490
2491
2492
2493 while ((count > 0) && (chan->slop_len < chan->frag_size)) {
2494 size_t slop_left = chan->frag_size - chan->slop_len;
2495
2496 size = (count < slop_left) ? count : slop_left;
2497 if (copy_from_user (chan->pgtbl[n / (PAGE_SIZE / chan->frag_size)].cpuaddr + (n % (PAGE_SIZE / chan->frag_size)) * chan->frag_size + chan->slop_len,
2498 userbuf, size)) {
2499 ret = -EFAULT;
2500 goto out;
2501 }
2502
2503 count -= size;
2504 chan->slop_len += size;
2505 userbuf += size;
2506 }
2507
2508
2509
2510
2511
2512 if (chan->slop_len < chan->frag_size) {
2513 sgtable[n].count = cpu_to_le32 (chan->slop_len | VIA_EOL | VIA_STOP);
2514 goto out;
2515 }
2516
2517
2518
2519
2520
2521
2522
2523 if (n == (chan->frag_number - 1))
2524 sgtable[n].count = cpu_to_le32 (chan->frag_size | VIA_EOL);
2525 else
2526 sgtable[n].count = cpu_to_le32 (chan->frag_size | VIA_FLAG);
2527
2528
2529
2530
2531 if (chan->sw_ptr == (chan->frag_number - 1))
2532 chan->sw_ptr = 0;
2533 else
2534 chan->sw_ptr++;
2535
2536
2537 assert (atomic_read (&chan->n_frags) > 0);
2538 atomic_dec (&chan->n_frags);
2539
2540
2541 chan->slop_len = 0;
2542
2543
2544 via_chan_maybe_start (chan);
2545
2546 DPRINTK ("Flushed block %u, sw_ptr now %u, n_frags now %d\n",
2547 n, chan->sw_ptr, atomic_read (&chan->n_frags));
2548
2549 DPRINTK ("regs==S=%02X C=%02X TP=%02X BP=%08X RT=%08X SG=%08X CC=%08X SS=%08X\n",
2550 inb (card->baseaddr + 0x00),
2551 inb (card->baseaddr + 0x01),
2552 inb (card->baseaddr + 0x02),
2553 inl (card->baseaddr + 0x04),
2554 inl (card->baseaddr + 0x08),
2555 inl (card->baseaddr + 0x0C),
2556 inl (card->baseaddr + 0x80),
2557 inl (card->baseaddr + 0x84));
2558
2559 if (count > 0)
2560 goto handle_one_block;
2561
2562out:
2563 if (userbuf - orig_userbuf)
2564 return userbuf - orig_userbuf;
2565 else
2566 return ret;
2567}
2568
2569
2570static ssize_t via_dsp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
2571{
2572 struct via_info *card;
2573 ssize_t rc;
2574 int nonblock = (file->f_flags & O_NONBLOCK);
2575
2576 DPRINTK ("ENTER, file=%p, buffer=%p, count=%u, ppos=%lu\n",
2577 file, buffer, count, ppos ? ((unsigned long)*ppos) : 0);
2578
2579 assert (file != NULL);
2580 card = file->private_data;
2581 assert (card != NULL);
2582
2583 if (ppos != &file->f_pos) {
2584 DPRINTK ("EXIT, returning -ESPIPE\n");
2585 return -ESPIPE;
2586 }
2587
2588 rc = via_syscall_down (card, nonblock);
2589 if (rc) goto out;
2590
2591 if (card->ch_out.is_mapped) {
2592 rc = -ENXIO;
2593 goto out_up;
2594 }
2595
2596 via_chan_set_buffering(card, &card->ch_out, -1);
2597 rc = via_chan_buffer_init (card, &card->ch_out);
2598
2599 if (rc)
2600 goto out_up;
2601
2602 rc = via_dsp_do_write (card, buffer, count, nonblock);
2603
2604out_up:
2605 up (&card->syscall_sem);
2606out:
2607 DPRINTK ("EXIT, returning %ld\n",(long) rc);
2608 return rc;
2609}
2610
2611
2612static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wait)
2613{
2614 struct via_info *card;
2615 struct via_channel *chan;
2616 unsigned int mask = 0;
2617
2618 DPRINTK ("ENTER\n");
2619
2620 assert (file != NULL);
2621 card = file->private_data;
2622 assert (card != NULL);
2623
2624 if (file->f_mode & FMODE_READ) {
2625 chan = &card->ch_in;
2626 if (sg_active (chan->iobase))
2627 poll_wait(file, &chan->wait, wait);
2628 if (atomic_read (&chan->n_frags) > 0)
2629 mask |= POLLIN | POLLRDNORM;
2630 }
2631
2632 if (file->f_mode & FMODE_WRITE) {
2633 chan = &card->ch_out;
2634 if (sg_active (chan->iobase))
2635 poll_wait(file, &chan->wait, wait);
2636 if (atomic_read (&chan->n_frags) > 0)
2637 mask |= POLLOUT | POLLWRNORM;
2638 }
2639
2640 DPRINTK ("EXIT, returning %u\n", mask);
2641 return mask;
2642}
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657static int via_dsp_drain_playback (struct via_info *card,
2658 struct via_channel *chan, int nonblock)
2659{
2660 DECLARE_WAITQUEUE(wait, current);
2661 int ret = 0;
2662
2663 DPRINTK ("ENTER, nonblock = %d\n", nonblock);
2664
2665 if (chan->slop_len > 0)
2666 via_chan_flush_frag (chan);
2667
2668 if (atomic_read (&chan->n_frags) == chan->frag_number)
2669 goto out;
2670
2671 via_chan_maybe_start (chan);
2672
2673 add_wait_queue(&chan->wait, &wait);
2674 for (;;) {
2675 DPRINTK ("FRAGS %d FRAGNUM %d\n", atomic_read(&chan->n_frags), chan->frag_number);
2676 __set_current_state(TASK_INTERRUPTIBLE);
2677 if (atomic_read (&chan->n_frags) >= chan->frag_number)
2678 break;
2679
2680 if (nonblock) {
2681 DPRINTK ("EXIT, returning -EAGAIN\n");
2682 ret = -EAGAIN;
2683 break;
2684 }
2685
2686#ifdef VIA_DEBUG
2687 {
2688 u8 r40,r41,r42,r43,r44,r48;
2689 pci_read_config_byte (card->pdev, 0x40, &r40);
2690 pci_read_config_byte (card->pdev, 0x41, &r41);
2691 pci_read_config_byte (card->pdev, 0x42, &r42);
2692 pci_read_config_byte (card->pdev, 0x43, &r43);
2693 pci_read_config_byte (card->pdev, 0x44, &r44);
2694 pci_read_config_byte (card->pdev, 0x48, &r48);
2695 DPRINTK ("PCI config: %02X %02X %02X %02X %02X %02X\n",
2696 r40,r41,r42,r43,r44,r48);
2697
2698 DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n",
2699 inb (card->baseaddr + 0x00),
2700 inb (card->baseaddr + 0x01),
2701 inb (card->baseaddr + 0x02),
2702 inl (card->baseaddr + 0x04),
2703 inl (card->baseaddr + 0x0C),
2704 inl (card->baseaddr + 0x80),
2705 inl (card->baseaddr + 0x84));
2706 }
2707
2708 if (!chan->is_active)
2709 printk (KERN_ERR "sleeping but not active\n");
2710#endif
2711
2712 up(&card->syscall_sem);
2713
2714 DPRINTK ("sleeping, nbufs=%d\n", atomic_read (&chan->n_frags));
2715 schedule();
2716
2717 if ((ret = via_syscall_down (card, nonblock)))
2718 break;
2719
2720 if (signal_pending (current)) {
2721 DPRINTK ("EXIT, returning -ERESTARTSYS\n");
2722 ret = -ERESTARTSYS;
2723 break;
2724 }
2725 }
2726 set_current_state(TASK_RUNNING);
2727 remove_wait_queue(&chan->wait, &wait);
2728
2729#ifdef VIA_DEBUG
2730 {
2731 u8 r40,r41,r42,r43,r44,r48;
2732 pci_read_config_byte (card->pdev, 0x40, &r40);
2733 pci_read_config_byte (card->pdev, 0x41, &r41);
2734 pci_read_config_byte (card->pdev, 0x42, &r42);
2735 pci_read_config_byte (card->pdev, 0x43, &r43);
2736 pci_read_config_byte (card->pdev, 0x44, &r44);
2737 pci_read_config_byte (card->pdev, 0x48, &r48);
2738 DPRINTK ("PCI config: %02X %02X %02X %02X %02X %02X\n",
2739 r40,r41,r42,r43,r44,r48);
2740
2741 DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n",
2742 inb (card->baseaddr + 0x00),
2743 inb (card->baseaddr + 0x01),
2744 inb (card->baseaddr + 0x02),
2745 inl (card->baseaddr + 0x04),
2746 inl (card->baseaddr + 0x0C),
2747 inl (card->baseaddr + 0x80),
2748 inl (card->baseaddr + 0x84));
2749
2750 DPRINTK ("final nbufs=%d\n", atomic_read (&chan->n_frags));
2751 }
2752#endif
2753
2754out:
2755 DPRINTK ("EXIT, returning %d\n", ret);
2756 return ret;
2757}
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771static int via_dsp_ioctl_space (struct via_info *card,
2772 struct via_channel *chan,
2773 void *arg)
2774{
2775 audio_buf_info info;
2776
2777 via_chan_set_buffering(card, chan, -1);
2778
2779 info.fragstotal = chan->frag_number;
2780 info.fragsize = chan->frag_size;
2781
2782
2783 info.fragments = atomic_read (&chan->n_frags);
2784
2785 if ((chan->slop_len % chan->frag_size > 0) && (info.fragments > 0))
2786 info.fragments--;
2787
2788
2789
2790
2791 info.bytes = (info.fragments * chan->frag_size);
2792 if (chan->slop_len % chan->frag_size > 0)
2793 info.bytes += chan->frag_size - (chan->slop_len % chan->frag_size);
2794
2795 DPRINTK ("EXIT, returning fragstotal=%d, fragsize=%d, fragments=%d, bytes=%d\n",
2796 info.fragstotal,
2797 info.fragsize,
2798 info.fragments,
2799 info.bytes);
2800
2801 return copy_to_user (arg, &info, sizeof (info))?-EFAULT:0;
2802}
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816static int via_dsp_ioctl_ptr (struct via_info *card,
2817 struct via_channel *chan,
2818 void *arg)
2819{
2820 count_info info;
2821
2822 spin_lock_irq (&card->lock);
2823
2824 info.bytes = chan->bytes;
2825 info.blocks = chan->n_irqs;
2826 chan->n_irqs = 0;
2827
2828 spin_unlock_irq (&card->lock);
2829
2830 if (chan->is_active) {
2831 unsigned long extra;
2832 info.ptr = atomic_read (&chan->hw_ptr) * chan->frag_size;
2833 extra = chan->frag_size - via_sg_offset(chan);
2834 info.ptr += extra;
2835 info.bytes += extra;
2836 } else {
2837 info.ptr = 0;
2838 }
2839
2840 DPRINTK ("EXIT, returning bytes=%d, blocks=%d, ptr=%d\n",
2841 info.bytes,
2842 info.blocks,
2843 info.ptr);
2844
2845 return copy_to_user (arg, &info, sizeof (info))?-EFAULT:0;
2846}
2847
2848
2849static int via_dsp_ioctl_trigger (struct via_channel *chan, int val)
2850{
2851 int enable, do_something;
2852
2853 if (chan->is_record)
2854 enable = (val & PCM_ENABLE_INPUT);
2855 else
2856 enable = (val & PCM_ENABLE_OUTPUT);
2857
2858 if (!chan->is_enabled && enable) {
2859 do_something = 1;
2860 } else if (chan->is_enabled && !enable) {
2861 do_something = -1;
2862 } else {
2863 do_something = 0;
2864 }
2865
2866 DPRINTK ("enable=%d, do_something=%d\n",
2867 enable, do_something);
2868
2869 if (chan->is_active && do_something)
2870 return -EINVAL;
2871
2872 if (do_something == 1) {
2873 chan->is_enabled = 1;
2874 via_chan_maybe_start (chan);
2875 DPRINTK ("Triggering input\n");
2876 }
2877
2878 else if (do_something == -1) {
2879 chan->is_enabled = 0;
2880 DPRINTK ("Setup input trigger\n");
2881 }
2882
2883 return 0;
2884}
2885
2886
2887static int via_dsp_ioctl (struct inode *inode, struct file *file,
2888 unsigned int cmd, unsigned long arg)
2889{
2890 int rc, rd=0, wr=0, val=0;
2891 struct via_info *card;
2892 struct via_channel *chan;
2893 int nonblock = (file->f_flags & O_NONBLOCK);
2894
2895 assert (file != NULL);
2896 card = file->private_data;
2897 assert (card != NULL);
2898
2899 if (file->f_mode & FMODE_WRITE)
2900 wr = 1;
2901 if (file->f_mode & FMODE_READ)
2902 rd = 1;
2903
2904 rc = via_syscall_down (card, nonblock);
2905 if (rc)
2906 return rc;
2907 rc = -EINVAL;
2908
2909 switch (cmd) {
2910
2911
2912 case OSS_GETVERSION:
2913 DPRINTK ("ioctl OSS_GETVERSION, EXIT, returning SOUND_VERSION\n");
2914 rc = put_user (SOUND_VERSION, (int *)arg);
2915 break;
2916
2917
2918 case SNDCTL_DSP_GETFMTS:
2919 DPRINTK ("DSP_GETFMTS, EXIT, returning AFMT U8|S16_LE\n");
2920 rc = put_user (AFMT_U8 | AFMT_S16_LE, (int *)arg);
2921 break;
2922
2923
2924 case SNDCTL_DSP_SETFMT:
2925 if (get_user(val, (int *)arg)) {
2926 rc = -EFAULT;
2927 break;
2928 }
2929 DPRINTK ("DSP_SETFMT, val==%d\n", val);
2930 if (val != AFMT_QUERY) {
2931 rc = 0;
2932
2933 if (rd)
2934 rc = via_chan_set_fmt (card, &card->ch_in, val);
2935
2936 if (rc >= 0 && wr)
2937 rc = via_chan_set_fmt (card, &card->ch_out, val);
2938
2939 if (rc < 0)
2940 break;
2941
2942 val = rc;
2943 } else {
2944 if ((rd && (card->ch_in.pcm_fmt & VIA_PCM_FMT_16BIT)) ||
2945 (wr && (card->ch_out.pcm_fmt & VIA_PCM_FMT_16BIT)))
2946 val = AFMT_S16_LE;
2947 else
2948 val = AFMT_U8;
2949 }
2950 DPRINTK ("SETFMT EXIT, returning %d\n", val);
2951 rc = put_user (val, (int *)arg);
2952 break;
2953
2954
2955 case SNDCTL_DSP_CHANNELS:
2956 if (get_user(val, (int *)arg)) {
2957 rc = -EFAULT;
2958 break;
2959 }
2960 DPRINTK ("DSP_CHANNELS, val==%d\n", val);
2961 if (val != 0) {
2962 rc = 0;
2963
2964 if (rd)
2965 rc = via_chan_set_stereo (card, &card->ch_in, val);
2966
2967 if (rc >= 0 && wr)
2968 rc = via_chan_set_stereo (card, &card->ch_out, val);
2969
2970 if (rc < 0)
2971 break;
2972
2973 val = rc;
2974 } else {
2975 if (rd)
2976 val = card->ch_in.channels;
2977 else
2978 val = card->ch_out.channels;
2979 }
2980 DPRINTK ("CHANNELS EXIT, returning %d\n", val);
2981 rc = put_user (val, (int *)arg);
2982 break;
2983
2984
2985 case SNDCTL_DSP_STEREO:
2986 if (get_user(val, (int *)arg)) {
2987 rc = -EFAULT;
2988 break;
2989 }
2990 DPRINTK ("DSP_STEREO, val==%d\n", val);
2991 rc = 0;
2992
2993 if (rd)
2994 rc = via_chan_set_stereo (card, &card->ch_in, val ? 2 : 1);
2995 if (rc >= 0 && wr)
2996 rc = via_chan_set_stereo (card, &card->ch_out, val ? 2 : 1);
2997
2998 if (rc < 0)
2999 break;
3000
3001 val = rc - 1;
3002
3003 DPRINTK ("STEREO EXIT, returning %d\n", val);
3004 rc = put_user(val, (int *) arg);
3005 break;
3006
3007
3008 case SNDCTL_DSP_SPEED:
3009 if (get_user(val, (int *)arg)) {
3010 rc = -EFAULT;
3011 break;
3012 }
3013 DPRINTK ("DSP_SPEED, val==%d\n", val);
3014 if (val < 0) {
3015 rc = -EINVAL;
3016 break;
3017 }
3018 if (val > 0) {
3019 rc = 0;
3020
3021 if (rd)
3022 rc = via_chan_set_speed (card, &card->ch_in, val);
3023 if (rc >= 0 && wr)
3024 rc = via_chan_set_speed (card, &card->ch_out, val);
3025
3026 if (rc < 0)
3027 break;
3028
3029 val = rc;
3030 } else {
3031 if (rd)
3032 val = card->ch_in.rate;
3033 else if (wr)
3034 val = card->ch_out.rate;
3035 else
3036 val = 0;
3037 }
3038 DPRINTK ("SPEED EXIT, returning %d\n", val);
3039 rc = put_user (val, (int *)arg);
3040 break;
3041
3042
3043 case SNDCTL_DSP_SYNC:
3044 DPRINTK ("DSP_SYNC\n");
3045 rc = 0;
3046 if (wr) {
3047 DPRINTK ("SYNC EXIT (after calling via_dsp_drain_playback)\n");
3048 rc = via_dsp_drain_playback (card, &card->ch_out, nonblock);
3049 }
3050 break;
3051
3052
3053 case SNDCTL_DSP_RESET:
3054 DPRINTK ("DSP_RESET\n");
3055 if (rd) {
3056 via_chan_clear (card, &card->ch_in);
3057 card->ch_in.frag_number = 0;
3058 card->ch_in.frag_size = 0;
3059 atomic_set(&card->ch_in.n_frags, 0);
3060 }
3061
3062 if (wr) {
3063 via_chan_clear (card, &card->ch_out);
3064 card->ch_out.frag_number = 0;
3065 card->ch_out.frag_size = 0;
3066 atomic_set(&card->ch_out.n_frags, 0);
3067 }
3068
3069 rc = 0;
3070 break;
3071
3072 case SNDCTL_DSP_NONBLOCK:
3073 file->f_flags |= O_NONBLOCK;
3074 rc = 0;
3075 break;
3076
3077
3078 case SNDCTL_DSP_GETCAPS:
3079 DPRINTK ("DSP_GETCAPS\n");
3080 rc = put_user(VIA_DSP_CAP, (int *)arg);
3081 break;
3082
3083
3084 case SNDCTL_DSP_GETBLKSIZE:
3085 DPRINTK ("DSP_GETBLKSIZE\n");
3086
3087 if (rd) {
3088 via_chan_set_buffering(card, &card->ch_in, -1);
3089 rc = put_user(card->ch_in.frag_size, (int *)arg);
3090 } else if (wr) {
3091 via_chan_set_buffering(card, &card->ch_out, -1);
3092 rc = put_user(card->ch_out.frag_size, (int *)arg);
3093 }
3094 break;
3095
3096
3097 case SNDCTL_DSP_GETISPACE:
3098 DPRINTK ("DSP_GETISPACE\n");
3099 if (rd)
3100 rc = via_dsp_ioctl_space (card, &card->ch_in, (void*) arg);
3101 break;
3102
3103
3104 case SNDCTL_DSP_GETOSPACE:
3105 DPRINTK ("DSP_GETOSPACE\n");
3106 if (wr)
3107 rc = via_dsp_ioctl_space (card, &card->ch_out, (void*) arg);
3108 break;
3109
3110
3111 case SNDCTL_DSP_GETIPTR:
3112 DPRINTK ("DSP_GETIPTR\n");
3113 if (rd)
3114 rc = via_dsp_ioctl_ptr (card, &card->ch_in, (void*) arg);
3115 break;
3116
3117
3118 case SNDCTL_DSP_GETOPTR:
3119 DPRINTK ("DSP_GETOPTR\n");
3120 if (wr)
3121 rc = via_dsp_ioctl_ptr (card, &card->ch_out, (void*) arg);
3122 break;
3123
3124
3125 case SNDCTL_DSP_GETODELAY:
3126 {
3127 DPRINTK ("DSP_GETODELAY\n");
3128
3129 chan = &card->ch_out;
3130
3131 if (!wr)
3132 break;
3133
3134 if (chan->is_active) {
3135
3136 val = chan->frag_number - atomic_read (&chan->n_frags);
3137
3138 assert(val >= 0);
3139
3140 if (val > 0) {
3141 val *= chan->frag_size;
3142 val -= chan->frag_size - via_sg_offset(chan);
3143 }
3144 val += chan->slop_len % chan->frag_size;
3145 } else
3146 val = 0;
3147
3148 assert (val <= (chan->frag_size * chan->frag_number));
3149
3150 DPRINTK ("GETODELAY EXIT, val = %d bytes\n", val);
3151 rc = put_user (val, (int *)arg);
3152 break;
3153 }
3154
3155
3156
3157
3158
3159 case SNDCTL_DSP_SETTRIGGER:
3160 if (get_user(val, (int *)arg)) {
3161 rc = -EFAULT;
3162 break;
3163 }
3164 DPRINTK ("DSP_SETTRIGGER, rd=%d, wr=%d, act=%d/%d, en=%d/%d\n",
3165 rd, wr, card->ch_in.is_active, card->ch_out.is_active,
3166 card->ch_in.is_enabled, card->ch_out.is_enabled);
3167
3168 rc = 0;
3169
3170 if (rd)
3171 rc = via_dsp_ioctl_trigger (&card->ch_in, val);
3172
3173 if (!rc && wr)
3174 rc = via_dsp_ioctl_trigger (&card->ch_out, val);
3175
3176 break;
3177
3178 case SNDCTL_DSP_GETTRIGGER:
3179 val = 0;
3180 if ((file->f_mode & FMODE_READ) && card->ch_in.is_enabled)
3181 val |= PCM_ENABLE_INPUT;
3182 if ((file->f_mode & FMODE_WRITE) && card->ch_out.is_enabled)
3183 val |= PCM_ENABLE_OUTPUT;
3184 rc = put_user(val, (int *)arg);
3185 break;
3186
3187
3188
3189
3190 case SNDCTL_DSP_SETDUPLEX:
3191 DPRINTK ("DSP_SETDUPLEX\n");
3192 if (!rd || !wr)
3193 break;
3194 rc = 0;
3195 break;
3196
3197
3198 case SNDCTL_DSP_SETFRAGMENT:
3199 if (get_user(val, (int *)arg)) {
3200 rc = -EFAULT;
3201 break;
3202 }
3203 DPRINTK ("DSP_SETFRAGMENT, val==%d\n", val);
3204
3205 if (rd)
3206 rc = via_chan_set_buffering(card, &card->ch_in, val);
3207
3208 if (wr)
3209 rc = via_chan_set_buffering(card, &card->ch_out, val);
3210
3211 DPRINTK ("SNDCTL_DSP_SETFRAGMENT (fragshift==0x%04X (%d), maxfrags==0x%04X (%d))\n",
3212 val & 0xFFFF,
3213 val & 0xFFFF,
3214 (val >> 16) & 0xFFFF,
3215 (val >> 16) & 0xFFFF);
3216
3217 rc = 0;
3218 break;
3219
3220
3221 case SNDCTL_DSP_POST:
3222 DPRINTK ("DSP_POST\n");
3223 if (wr) {
3224 if (card->ch_out.slop_len > 0)
3225 via_chan_flush_frag (&card->ch_out);
3226 via_chan_maybe_start (&card->ch_out);
3227 }
3228
3229 rc = 0;
3230 break;
3231
3232
3233 default:
3234 DPRINTK ("unhandled ioctl, cmd==%u, arg==%p\n",
3235 cmd, (void*) arg);
3236 break;
3237 }
3238
3239 up (&card->syscall_sem);
3240 DPRINTK ("EXIT, returning %d\n", rc);
3241 return rc;
3242}
3243
3244
3245static int via_dsp_open (struct inode *inode, struct file *file)
3246{
3247 int minor = MINOR(inode->i_rdev);
3248 struct via_info *card;
3249 struct pci_dev *pdev;
3250 struct via_channel *chan;
3251 struct pci_driver *drvr;
3252 int nonblock = (file->f_flags & O_NONBLOCK);
3253
3254 DPRINTK ("ENTER, minor=%d, file->f_mode=0x%x\n", minor, file->f_mode);
3255
3256 if (!(file->f_mode & (FMODE_READ | FMODE_WRITE))) {
3257 DPRINTK ("EXIT, returning -EINVAL\n");
3258 return -EINVAL;
3259 }
3260
3261 card = NULL;
3262 pci_for_each_dev(pdev) {
3263 drvr = pci_dev_driver (pdev);
3264 if (drvr == &via_driver) {
3265 assert (pci_get_drvdata (pdev) != NULL);
3266
3267 card = pci_get_drvdata (pdev);
3268 DPRINTK ("dev_dsp = %d, minor = %d, assn = %d\n",
3269 card->dev_dsp, minor,
3270 (card->dev_dsp ^ minor) & ~0xf);
3271
3272 if (((card->dev_dsp ^ minor) & ~0xf) == 0)
3273 goto match;
3274 }
3275 }
3276
3277 DPRINTK ("no matching %s found\n", card ? "minor" : "driver");
3278 return -ENODEV;
3279
3280match:
3281 if (nonblock) {
3282 if (down_trylock (&card->open_sem)) {
3283 DPRINTK ("EXIT, returning -EAGAIN\n");
3284 return -EAGAIN;
3285 }
3286 } else {
3287 if (down_interruptible (&card->open_sem)) {
3288 DPRINTK ("EXIT, returning -ERESTARTSYS\n");
3289 return -ERESTARTSYS;
3290 }
3291 }
3292
3293 file->private_data = card;
3294 DPRINTK ("file->f_mode == 0x%x\n", file->f_mode);
3295
3296
3297 if (file->f_mode & FMODE_READ) {
3298 chan = &card->ch_in;
3299
3300 via_chan_init (card, chan);
3301
3302
3303 chan->pcm_fmt = VIA_PCM_FMT_16BIT | VIA_PCM_FMT_STEREO;
3304 chan->channels = 2;
3305
3306
3307 via_chan_pcm_fmt (chan, 0);
3308 via_set_rate (card->ac97, chan, 44100);
3309 }
3310
3311
3312 if (file->f_mode & FMODE_WRITE) {
3313 chan = &card->ch_out;
3314
3315 via_chan_init (card, chan);
3316
3317 if (file->f_mode & FMODE_READ) {
3318
3319
3320 chan->pcm_fmt = VIA_PCM_FMT_16BIT | VIA_PCM_FMT_STEREO;
3321 chan->channels = 2;
3322 via_chan_pcm_fmt (chan, 0);
3323 via_set_rate (card->ac97, chan, 44100);
3324 } else {
3325 if ((minor & 0xf) == SND_DEV_DSP16) {
3326 chan->pcm_fmt = VIA_PCM_FMT_16BIT;
3327 via_chan_pcm_fmt (chan, 0);
3328 via_set_rate (card->ac97, chan, 44100);
3329 } else {
3330 via_chan_pcm_fmt (chan, 1);
3331 via_set_rate (card->ac97, chan, 8000);
3332 }
3333 }
3334 }
3335
3336 DPRINTK ("EXIT, returning 0\n");
3337 return 0;
3338}
3339
3340
3341static int via_dsp_release(struct inode *inode, struct file *file)
3342{
3343 struct via_info *card;
3344 int nonblock = (file->f_flags & O_NONBLOCK);
3345 int rc;
3346
3347 DPRINTK ("ENTER\n");
3348
3349 assert (file != NULL);
3350 card = file->private_data;
3351 assert (card != NULL);
3352
3353 rc = via_syscall_down (card, nonblock);
3354 if (rc) {
3355 DPRINTK ("EXIT (syscall_down error), rc=%d\n", rc);
3356 return rc;
3357 }
3358
3359 if (file->f_mode & FMODE_WRITE) {
3360 rc = via_dsp_drain_playback (card, &card->ch_out, nonblock);
3361 if (rc && rc != ERESTARTSYS)
3362 printk (KERN_DEBUG "via_audio: ignoring drain playback error %d\n", rc);
3363
3364 via_chan_free (card, &card->ch_out);
3365 via_chan_buffer_free(card, &card->ch_out);
3366 }
3367
3368 if (file->f_mode & FMODE_READ) {
3369 via_chan_free (card, &card->ch_in);
3370 via_chan_buffer_free (card, &card->ch_in);
3371 }
3372
3373 up (&card->syscall_sem);
3374 up (&card->open_sem);
3375
3376 DPRINTK ("EXIT, returning 0\n");
3377 return 0;
3378}
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
3389{
3390#ifdef CONFIG_MIDI_VIA82CXXX
3391 u8 r42;
3392#endif
3393 int rc;
3394 struct via_info *card;
3395 static int printed_version = 0;
3396
3397 DPRINTK ("ENTER\n");
3398
3399 if (printed_version++ == 0)
3400 printk (KERN_INFO "Via 686a/8233/8235 audio driver " VIA_VERSION "\n");
3401
3402 rc = pci_enable_device (pdev);
3403 if (rc)
3404 goto err_out;
3405
3406
3407 rc = pci_request_regions (pdev, "via82cxxx_audio");
3408 if (rc)
3409 goto err_out_disable;
3410
3411 card = kmalloc (sizeof (*card), GFP_KERNEL);
3412 if (!card) {
3413 printk (KERN_ERR PFX "out of memory, aborting\n");
3414 rc = -ENOMEM;
3415 goto err_out_res;
3416 }
3417
3418 pci_set_drvdata (pdev, card);
3419
3420 memset (card, 0, sizeof (*card));
3421 card->pdev = pdev;
3422 card->baseaddr = pci_resource_start (pdev, 0);
3423 card->card_num = via_num_cards++;
3424 spin_lock_init (&card->lock);
3425 spin_lock_init (&card->ac97_lock);
3426 init_MUTEX (&card->syscall_sem);
3427 init_MUTEX (&card->open_sem);
3428
3429
3430 via_chan_init_defaults (card, &card->ch_out);
3431 via_chan_init_defaults (card, &card->ch_in);
3432 via_chan_init_defaults (card, &card->ch_fm);
3433
3434
3435
3436 if (pci_resource_start (pdev, 2) > 0)
3437 card->rev_h = 1;
3438
3439
3440
3441 card->intmask = id->driver_data;
3442 card->legacy = !card->intmask;
3443 card->sixchannel = id->driver_data;
3444
3445 if(card->sixchannel)
3446 printk(KERN_INFO PFX "Six channel audio available\n");
3447 if (pdev->irq < 1) {
3448 printk (KERN_ERR PFX "invalid PCI IRQ %d, aborting\n", pdev->irq);
3449 rc = -ENODEV;
3450 goto err_out_kfree;
3451 }
3452
3453 if (!(pci_resource_flags (pdev, 0) & IORESOURCE_IO)) {
3454 printk (KERN_ERR PFX "unable to locate I/O resources, aborting\n");
3455 rc = -ENODEV;
3456 goto err_out_kfree;
3457 }
3458
3459 pci_set_master(pdev);
3460
3461
3462
3463
3464 rc = via_ac97_init (card);
3465 if (rc) {
3466 printk (KERN_ERR PFX "AC97 init failed, aborting\n");
3467 goto err_out_kfree;
3468 }
3469
3470
3471
3472
3473 rc = via_dsp_init (card);
3474 if (rc) {
3475 printk (KERN_ERR PFX "DSP device init failed, aborting\n");
3476 goto err_out_have_mixer;
3477 }
3478
3479
3480
3481
3482 rc = via_card_init_proc (card);
3483 if (rc) {
3484 printk (KERN_ERR PFX "card-specific /proc init failed, aborting\n");
3485 goto err_out_have_dsp;
3486 }
3487
3488
3489
3490
3491 rc = via_interrupt_init (card);
3492 if (rc) {
3493 printk (KERN_ERR PFX "interrupt init failed, aborting\n");
3494 goto err_out_have_proc;
3495 }
3496
3497 printk (KERN_INFO PFX "board #%d at 0x%04lX, IRQ %d\n",
3498 card->card_num + 1, card->baseaddr, pdev->irq);
3499
3500#ifdef CONFIG_MIDI_VIA82CXXX
3501
3502 card->midi_info.io_base = 0;
3503
3504 if(card->legacy)
3505 {
3506 pci_read_config_byte (pdev, 0x42, &r42);
3507
3508 pci_write_config_byte (pdev, 0x42, r42 | VIA_CR42_MIDI_IRQMASK);
3509 if (r42 & VIA_CR42_MIDI_ENABLE)
3510 {
3511 if (r42 & VIA_CR42_MIDI_PNP)
3512 card->midi_info.io_base = pci_resource_start (pdev, 2);
3513 else
3514 {
3515 u8 r43;
3516 pci_read_config_byte (pdev, 0x43, &r43);
3517 card->midi_info.io_base = 0x300 + ((r43 & 0x0c) << 2);
3518 }
3519
3520 card->midi_info.irq = -pdev->irq;
3521 if (probe_uart401(& card->midi_info, THIS_MODULE))
3522 {
3523 card->midi_devc=midi_devs[card->midi_info.slots[4]]->devc;
3524 pci_write_config_byte(pdev, 0x42, r42 & ~VIA_CR42_MIDI_IRQMASK);
3525 printk("Enabled Via MIDI\n");
3526 }
3527 }
3528 }
3529#endif
3530
3531 DPRINTK ("EXIT, returning 0\n");
3532 return 0;
3533
3534err_out_have_proc:
3535 via_card_cleanup_proc (card);
3536
3537err_out_have_dsp:
3538 via_dsp_cleanup (card);
3539
3540err_out_have_mixer:
3541 via_ac97_cleanup (card);
3542
3543err_out_kfree:
3544#ifndef VIA_NDEBUG
3545 memset (card, 0xAB, sizeof (*card));
3546#endif
3547 kfree (card);
3548
3549err_out_res:
3550 pci_release_regions (pdev);
3551
3552err_out_disable:
3553 pci_disable_device (pdev);
3554
3555err_out:
3556 pci_set_drvdata (pdev, NULL);
3557 DPRINTK ("EXIT - returning %d\n", rc);
3558 return rc;
3559}
3560
3561
3562static void __devexit via_remove_one (struct pci_dev *pdev)
3563{
3564 struct via_info *card;
3565
3566 DPRINTK ("ENTER\n");
3567
3568 assert (pdev != NULL);
3569 card = pci_get_drvdata (pdev);
3570 assert (card != NULL);
3571
3572#ifdef CONFIG_MIDI_VIA82CXXX
3573 if (card->midi_info.io_base)
3574 unload_uart401(&card->midi_info);
3575#endif
3576
3577 free_irq (card->pdev->irq, card);
3578 via_card_cleanup_proc (card);
3579 via_dsp_cleanup (card);
3580 via_ac97_cleanup (card);
3581
3582#ifndef VIA_NDEBUG
3583 memset (card, 0xAB, sizeof (*card));
3584#endif
3585 kfree (card);
3586
3587 pci_set_drvdata (pdev, NULL);
3588
3589 pci_release_regions (pdev);
3590 pci_disable_device (pdev);
3591 pci_set_power_state (pdev, 3);
3592
3593 DPRINTK ("EXIT\n");
3594 return;
3595}
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605static int __init init_via82cxxx_audio(void)
3606{
3607 int rc;
3608
3609 DPRINTK ("ENTER\n");
3610
3611 rc = via_init_proc ();
3612 if (rc) {
3613 DPRINTK ("EXIT, returning %d\n", rc);
3614 return rc;
3615 }
3616
3617 rc = pci_register_driver (&via_driver);
3618 if (rc < 1) {
3619 if (rc == 0)
3620 pci_unregister_driver (&via_driver);
3621 via_cleanup_proc ();
3622 DPRINTK ("EXIT, returning -ENODEV\n");
3623 return -ENODEV;
3624 }
3625
3626 DPRINTK ("EXIT, returning 0\n");
3627 return 0;
3628}
3629
3630
3631static void __exit cleanup_via82cxxx_audio(void)
3632{
3633 DPRINTK ("ENTER\n");
3634
3635 pci_unregister_driver (&via_driver);
3636 via_cleanup_proc ();
3637
3638 DPRINTK ("EXIT\n");
3639}
3640
3641
3642module_init(init_via82cxxx_audio);
3643module_exit(cleanup_via82cxxx_audio);
3644
3645MODULE_AUTHOR("Jeff Garzik");
3646MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices");
3647MODULE_LICENSE("GPL");
3648
3649EXPORT_NO_SYMBOLS;
3650
3651
3652
3653#ifdef CONFIG_PROC_FS
3654
3655
3656
3657
3658
3659
3660
3661
3662static int via_info_read_proc (char *page, char **start, off_t off,
3663 int count, int *eof, void *data)
3664{
3665#define YN(val,bit) (((val) & (bit)) ? "yes" : "no")
3666#define ED(val,bit) (((val) & (bit)) ? "enable" : "disable")
3667
3668 int len = 0;
3669 u8 r40, r41, r42, r44;
3670 struct via_info *card = data;
3671
3672 DPRINTK ("ENTER\n");
3673
3674 assert (card != NULL);
3675
3676 len += sprintf (page+len, VIA_CARD_NAME "\n\n");
3677
3678 pci_read_config_byte (card->pdev, 0x40, &r40);
3679 pci_read_config_byte (card->pdev, 0x41, &r41);
3680 pci_read_config_byte (card->pdev, 0x42, &r42);
3681 pci_read_config_byte (card->pdev, 0x44, &r44);
3682
3683 len += sprintf (page+len,
3684 "Via 82Cxxx PCI registers:\n"
3685 "\n"
3686 "40 Codec Ready: %s\n"
3687 " Codec Low-power: %s\n"
3688 " Secondary Codec Ready: %s\n"
3689 "\n"
3690 "41 Interface Enable: %s\n"
3691 " De-Assert Reset: %s\n"
3692 " Force SYNC high: %s\n"
3693 " Force SDO high: %s\n"
3694 " Variable Sample Rate On-Demand Mode: %s\n"
3695 " SGD Read Channel PCM Data Out: %s\n"
3696 " FM Channel PCM Data Out: %s\n"
3697 " SB PCM Data Out: %s\n"
3698 "\n"
3699 "42 Game port enabled: %s\n"
3700 " SoundBlaster enabled: %s\n"
3701 " FM enabled: %s\n"
3702 " MIDI enabled: %s\n"
3703 "\n"
3704 "44 AC-Link Interface Access: %s\n"
3705 " Secondary Codec Support: %s\n"
3706
3707 "\n",
3708
3709 YN (r40, VIA_CR40_AC97_READY),
3710 YN (r40, VIA_CR40_AC97_LOW_POWER),
3711 YN (r40, VIA_CR40_SECONDARY_READY),
3712
3713 ED (r41, VIA_CR41_AC97_ENABLE),
3714 YN (r41, (1 << 6)),
3715 YN (r41, (1 << 5)),
3716 YN (r41, (1 << 4)),
3717 ED (r41, (1 << 3)),
3718 ED (r41, (1 << 2)),
3719 ED (r41, (1 << 1)),
3720 ED (r41, (1 << 0)),
3721
3722 YN (r42, VIA_CR42_GAME_ENABLE),
3723 YN (r42, VIA_CR42_SB_ENABLE),
3724 YN (r42, VIA_CR42_FM_ENABLE),
3725 YN (r42, VIA_CR42_MIDI_ENABLE),
3726
3727 YN (r44, VIA_CR44_AC_LINK_ACCESS),
3728 YN (r44, VIA_CR44_SECOND_CODEC_SUPPORT)
3729
3730 );
3731
3732 DPRINTK ("EXIT, returning %d\n", len);
3733 return len;
3734
3735#undef YN
3736#undef ED
3737}
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747static int __init via_init_proc (void)
3748{
3749 DPRINTK ("ENTER\n");
3750
3751 if (!proc_mkdir ("driver/via", 0))
3752 return -EIO;
3753
3754 DPRINTK ("EXIT, returning 0\n");
3755 return 0;
3756}
3757
3758
3759static void via_cleanup_proc (void)
3760{
3761 DPRINTK ("ENTER\n");
3762
3763 remove_proc_entry ("driver/via", NULL);
3764
3765 DPRINTK ("EXIT\n");
3766}
3767
3768
3769static int __init via_card_init_proc (struct via_info *card)
3770{
3771 char s[32];
3772 int rc;
3773
3774 DPRINTK ("ENTER\n");
3775
3776 sprintf (s, "driver/via/%d", card->card_num);
3777 if (!proc_mkdir (s, 0)) {
3778 rc = -EIO;
3779 goto err_out_none;
3780 }
3781
3782 sprintf (s, "driver/via/%d/info", card->card_num);
3783 if (!create_proc_read_entry (s, 0, 0, via_info_read_proc, card)) {
3784 rc = -EIO;
3785 goto err_out_dir;
3786 }
3787
3788 sprintf (s, "driver/via/%d/ac97", card->card_num);
3789 if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) {
3790 rc = -EIO;
3791 goto err_out_info;
3792 }
3793
3794 DPRINTK ("EXIT, returning 0\n");
3795 return 0;
3796
3797err_out_info:
3798 sprintf (s, "driver/via/%d/info", card->card_num);
3799 remove_proc_entry (s, NULL);
3800
3801err_out_dir:
3802 sprintf (s, "driver/via/%d", card->card_num);
3803 remove_proc_entry (s, NULL);
3804
3805err_out_none:
3806 DPRINTK ("EXIT, returning %d\n", rc);
3807 return rc;
3808}
3809
3810
3811static void via_card_cleanup_proc (struct via_info *card)
3812{
3813 char s[32];
3814
3815 DPRINTK ("ENTER\n");
3816
3817 sprintf (s, "driver/via/%d/ac97", card->card_num);
3818 remove_proc_entry (s, NULL);
3819
3820 sprintf (s, "driver/via/%d/info", card->card_num);
3821 remove_proc_entry (s, NULL);
3822
3823 sprintf (s, "driver/via/%d", card->card_num);
3824 remove_proc_entry (s, NULL);
3825
3826 DPRINTK ("EXIT\n");
3827}
3828
3829#endif
3830