diff options
author | Martin Habets <errandir_news@mph.eclipse.co.uk> | 2005-09-10 09:39:00 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-09-12 04:48:38 -0400 |
commit | 4338829e09db2d320a00b4e0ed0bcc49859d73cc (patch) | |
tree | 2e312913429ae7519c4fd32608caf734eac3cfa8 /sound/sparc | |
parent | afe0f1f6688f4c4c9235873121548e76dedd8ef8 (diff) |
[ALSA] Several fixes for the Sun DBRI driver
SPARC DBRI driver
This patch contains the following fixes to the Alsa DBRI driver:
- Remove 2.6.13 build warning on the prom_getproperty() call.
- Rework command synchronization: send a sequence number with D_WAIT,
and check it in the completion interrupt.
Move synchronization delays from _cmdsend() to _cmdlock() allowing the
CPU to do other usefull things while the DBRI is processing the
commands.
- Fix first argument of printk() calls.
- Enable burst transfers for DBRI. Original 2.4 patch from Krzysztof
Helt
- Make dbri_debug module parameter writable from sysfs. Remove obsolete
write access to the /proc debug file.
- Replace udelay() with msleep_interruptible() where possible.
- Update documentation comments.
Signed-off-by: Martin Habets <errandir_news@mph.eclipse.co.uk>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/sparc')
-rw-r--r-- | sound/sparc/dbri.c | 205 |
1 files changed, 103 insertions, 102 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index a56f81bb0049..b5c4c15ae7f0 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for DBRI sound chip found on Sparcs. | 2 | * Driver for DBRI sound chip found on Sparcs. |
3 | * Copyright (C) 2004 Martin Habets (mhabets@users.sourceforge.net) | 3 | * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net) |
4 | * | 4 | * |
5 | * Based entirely upon drivers/sbus/audio/dbri.c which is: | 5 | * Based entirely upon drivers/sbus/audio/dbri.c which is: |
6 | * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) | 6 | * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) |
@@ -43,6 +43,12 @@ | |||
43 | * audio devices. But the SUN HW group decided against it, at least on my | 43 | * audio devices. But the SUN HW group decided against it, at least on my |
44 | * LX the speakerbox connector has at least 1 pin missing and 1 wrongly | 44 | * LX the speakerbox connector has at least 1 pin missing and 1 wrongly |
45 | * connected. | 45 | * connected. |
46 | * | ||
47 | * I've tried to stick to the following function naming conventions: | ||
48 | * snd_* ALSA stuff | ||
49 | * cs4215_* CS4215 codec specfic stuff | ||
50 | * dbri_* DBRI high-level stuff | ||
51 | * other DBRI low-level stuff | ||
46 | */ | 52 | */ |
47 | 53 | ||
48 | #include <sound/driver.h> | 54 | #include <sound/driver.h> |
@@ -87,7 +93,7 @@ MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard."); | |||
87 | #define D_DESC (1<<5) | 93 | #define D_DESC (1<<5) |
88 | 94 | ||
89 | static int dbri_debug = 0; | 95 | static int dbri_debug = 0; |
90 | module_param(dbri_debug, int, 0444); | 96 | module_param(dbri_debug, int, 0644); |
91 | MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); | 97 | MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); |
92 | 98 | ||
93 | #ifdef DBRI_DEBUG | 99 | #ifdef DBRI_DEBUG |
@@ -320,7 +326,8 @@ typedef struct snd_dbri { | |||
320 | void __iomem *regs; /* dbri HW regs */ | 326 | void __iomem *regs; /* dbri HW regs */ |
321 | int dbri_version; /* 'e' and up is OK */ | 327 | int dbri_version; /* 'e' and up is OK */ |
322 | int dbri_irqp; /* intr queue pointer */ | 328 | int dbri_irqp; /* intr queue pointer */ |
323 | int wait_seen; | 329 | int wait_send; /* sequence of command buffers send */ |
330 | int wait_ackd; /* sequence of command buffers acknowledged */ | ||
324 | 331 | ||
325 | struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ | 332 | struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ |
326 | struct dbri_desc descs[DBRI_NO_DESCS]; | 333 | struct dbri_desc descs[DBRI_NO_DESCS]; |
@@ -625,16 +632,13 @@ static __u32 reverse_bytes(__u32 b, int len) | |||
625 | 632 | ||
626 | Commands are sent to the DBRI by building a list of them in memory, | 633 | Commands are sent to the DBRI by building a list of them in memory, |
627 | then writing the address of the first list item to DBRI register 8. | 634 | then writing the address of the first list item to DBRI register 8. |
628 | The list is terminated with a WAIT command, which can generate a | 635 | The list is terminated with a WAIT command, which generates a |
629 | CPU interrupt if required. | 636 | CPU interrupt to signal completion. |
630 | 637 | ||
631 | Since the DBRI can run in parallel with the CPU, several means of | 638 | Since the DBRI can run in parallel with the CPU, several means of |
632 | synchronization present themselves. The original scheme (Rudolf's) | 639 | synchronization present themselves. The method implemented here is close |
633 | was to set a flag when we "cmdlock"ed the DBRI, clear the flag when | 640 | to the original scheme (Rudolf's), and uses 2 counters (wait_send and |
634 | an interrupt signaled completion, and wait on a wait_queue if a routine | 641 | wait_ackd) to synchronize the command buffer between the CPU and the DBRI. |
635 | attempted to cmdlock while the flag was set. The problems arose when | ||
636 | we tried to cmdlock from inside an interrupt handler, which might | ||
637 | cause scheduling in an interrupt (if we waited), etc, etc | ||
638 | 642 | ||
639 | A more sophisticated scheme might involve a circular command buffer | 643 | A more sophisticated scheme might involve a circular command buffer |
640 | or an array of command buffers. A routine could fill one with | 644 | or an array of command buffers. A routine could fill one with |
@@ -642,70 +646,75 @@ commands and link it onto a list. When a interrupt signaled | |||
642 | completion of the current command buffer, look on the list for | 646 | completion of the current command buffer, look on the list for |
643 | the next one. | 647 | the next one. |
644 | 648 | ||
645 | I've decided to implement something much simpler - after each command, | ||
646 | the CPU waits for the DBRI to finish the command by polling the P bit | ||
647 | in DBRI register 0. I've tried to implement this in such a way | ||
648 | that might make implementing a more sophisticated scheme easier. | ||
649 | |||
650 | Every time a routine wants to write commands to the DBRI, it must | 649 | Every time a routine wants to write commands to the DBRI, it must |
651 | first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd | 650 | first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd |
652 | in return. After the commands have been writen, dbri_cmdsend() is | 651 | in return. dbri_cmdlock() will block if the previous commands have not |
653 | called with the final pointer value. | 652 | been completed yet. After this the commands can be written to the buffer, |
653 | and dbri_cmdsend() is called with the final pointer value to send them | ||
654 | to the DBRI. | ||
654 | 655 | ||
655 | */ | 656 | */ |
656 | 657 | ||
658 | static void dbri_process_interrupt_buffer(snd_dbri_t * dbri); | ||
659 | |||
657 | enum dbri_lock_t { NoGetLock, GetLock }; | 660 | enum dbri_lock_t { NoGetLock, GetLock }; |
661 | #define MAXLOOPS 10 | ||
658 | 662 | ||
659 | static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get) | 663 | static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get) |
660 | { | 664 | { |
665 | int maxloops = MAXLOOPS; | ||
666 | |||
661 | #ifndef SMP | 667 | #ifndef SMP |
662 | if ((get == GetLock) && spin_is_locked(&dbri->lock)) { | 668 | if ((get == GetLock) && spin_is_locked(&dbri->lock)) { |
663 | printk(KERN_ERR "DBRI: cmdlock called while in spinlock."); | 669 | printk(KERN_ERR "DBRI: cmdlock called while in spinlock."); |
664 | } | 670 | } |
665 | #endif | 671 | #endif |
666 | 672 | ||
673 | /* Delay if previous commands are still being processed */ | ||
674 | while ((--maxloops) > 0 && (dbri->wait_send != dbri->wait_ackd)) { | ||
675 | msleep_interruptible(1); | ||
676 | /* If dbri_cmdlock() got called from inside the | ||
677 | * interrupt handler, this will do the processing. | ||
678 | */ | ||
679 | dbri_process_interrupt_buffer(dbri); | ||
680 | } | ||
681 | if (maxloops == 0) { | ||
682 | printk(KERN_ERR "DBRI: Chip never completed command buffer %d\n", | ||
683 | dbri->wait_send); | ||
684 | } else { | ||
685 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", | ||
686 | MAXLOOPS - maxloops - 1); | ||
687 | } | ||
688 | |||
667 | /*if (get == GetLock) spin_lock(&dbri->lock); */ | 689 | /*if (get == GetLock) spin_lock(&dbri->lock); */ |
668 | return &dbri->dma->cmd[0]; | 690 | return &dbri->dma->cmd[0]; |
669 | } | 691 | } |
670 | 692 | ||
671 | static void dbri_process_interrupt_buffer(snd_dbri_t *); | ||
672 | |||
673 | static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd) | 693 | static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd) |
674 | { | 694 | { |
675 | int MAXLOOPS = 1000000; | ||
676 | int maxloops = MAXLOOPS; | ||
677 | volatile s32 *ptr; | 695 | volatile s32 *ptr; |
696 | u32 reg; | ||
678 | 697 | ||
679 | for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { | 698 | for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { |
680 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | 699 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); |
681 | } | 700 | } |
682 | 701 | ||
683 | if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { | 702 | if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { |
684 | printk("DBRI: Command buffer overflow! (bug in driver)\n"); | 703 | printk(KERN_ERR "DBRI: Command buffer overflow! (bug in driver)\n"); |
685 | /* Ignore the last part. */ | 704 | /* Ignore the last part. */ |
686 | cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; | 705 | cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; |
687 | } | 706 | } |
688 | 707 | ||
708 | dbri->wait_send++; | ||
709 | dbri->wait_send &= 0xffff; /* restrict it to a 16 bit counter. */ | ||
689 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | 710 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); |
690 | *(cmd++) = DBRI_CMD(D_WAIT, 1, 0); | 711 | *(cmd++) = DBRI_CMD(D_WAIT, 1, dbri->wait_send); |
691 | dbri->wait_seen = 0; | 712 | |
713 | /* Set command pointer and signal it is valid. */ | ||
692 | sbus_writel(dbri->dma_dvma, dbri->regs + REG8); | 714 | sbus_writel(dbri->dma_dvma, dbri->regs + REG8); |
693 | while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) | 715 | reg = sbus_readl(dbri->regs + REG0); |
694 | barrier(); | 716 | reg |= D_P; |
695 | if (maxloops == 0) { | 717 | sbus_writel(reg, dbri->regs + REG0); |
696 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); | ||
697 | dprintk(D_CMD, "DBRI: Chip never completed command buffer\n"); | ||
698 | } else { | ||
699 | while ((--maxloops) > 0 && (!dbri->wait_seen)) | ||
700 | dbri_process_interrupt_buffer(dbri); | ||
701 | if (maxloops == 0) { | ||
702 | printk(KERN_ERR "DBRI: Chip never acked WAIT\n"); | ||
703 | dprintk(D_CMD, "DBRI: Chip never acked WAIT\n"); | ||
704 | } else { | ||
705 | dprintk(D_CMD, "Chip completed command " | ||
706 | "buffer (%d)\n", MAXLOOPS - maxloops); | ||
707 | } | ||
708 | } | ||
709 | 718 | ||
710 | /*spin_unlock(&dbri->lock); */ | 719 | /*spin_unlock(&dbri->lock); */ |
711 | } | 720 | } |
@@ -757,10 +766,11 @@ static void dbri_initialize(snd_dbri_t * dbri) | |||
757 | for (n = 0; n < DBRI_NO_PIPES; n++) | 766 | for (n = 0; n < DBRI_NO_PIPES; n++) |
758 | dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; | 767 | dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; |
759 | 768 | ||
760 | /* We should query the openprom to see what burst sizes this | 769 | /* A brute approach - DBRI falls back to working burst size by itself |
761 | * SBus supports. For now, just disable all SBus bursts */ | 770 | * On SS20 D_S does not work, so do not try so high. */ |
762 | tmp = sbus_readl(dbri->regs + REG0); | 771 | tmp = sbus_readl(dbri->regs + REG0); |
763 | tmp &= ~(D_G | D_S | D_E); | 772 | tmp |= D_G | D_E; |
773 | tmp &= ~D_S; | ||
764 | sbus_writel(tmp, dbri->regs + REG0); | 774 | sbus_writel(tmp, dbri->regs + REG0); |
765 | 775 | ||
766 | /* | 776 | /* |
@@ -805,13 +815,13 @@ static void reset_pipe(snd_dbri_t * dbri, int pipe) | |||
805 | volatile int *cmd; | 815 | volatile int *cmd; |
806 | 816 | ||
807 | if (pipe < 0 || pipe > 31) { | 817 | if (pipe < 0 || pipe > 31) { |
808 | printk("DBRI: reset_pipe called with illegal pipe number\n"); | 818 | printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n"); |
809 | return; | 819 | return; |
810 | } | 820 | } |
811 | 821 | ||
812 | sdp = dbri->pipes[pipe].sdp; | 822 | sdp = dbri->pipes[pipe].sdp; |
813 | if (sdp == 0) { | 823 | if (sdp == 0) { |
814 | printk("DBRI: reset_pipe called on uninitialized pipe\n"); | 824 | printk(KERN_ERR "DBRI: reset_pipe called on uninitialized pipe\n"); |
815 | return; | 825 | return; |
816 | } | 826 | } |
817 | 827 | ||
@@ -834,12 +844,12 @@ static void reset_pipe(snd_dbri_t * dbri, int pipe) | |||
834 | static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp) | 844 | static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp) |
835 | { | 845 | { |
836 | if (pipe < 0 || pipe > 31) { | 846 | if (pipe < 0 || pipe > 31) { |
837 | printk("DBRI: setup_pipe called with illegal pipe number\n"); | 847 | printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n"); |
838 | return; | 848 | return; |
839 | } | 849 | } |
840 | 850 | ||
841 | if ((sdp & 0xf800) != sdp) { | 851 | if ((sdp & 0xf800) != sdp) { |
842 | printk("DBRI: setup_pipe called with strange SDP value\n"); | 852 | printk(KERN_ERR "DBRI: setup_pipe called with strange SDP value\n"); |
843 | /* sdp &= 0xf800; */ | 853 | /* sdp &= 0xf800; */ |
844 | } | 854 | } |
845 | 855 | ||
@@ -872,13 +882,13 @@ static void link_time_slot(snd_dbri_t * dbri, int pipe, | |||
872 | int nextpipe; | 882 | int nextpipe; |
873 | 883 | ||
874 | if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) { | 884 | if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) { |
875 | printk | 885 | printk(KERN_ERR |
876 | ("DBRI: link_time_slot called with illegal pipe number\n"); | 886 | "DBRI: link_time_slot called with illegal pipe number\n"); |
877 | return; | 887 | return; |
878 | } | 888 | } |
879 | 889 | ||
880 | if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) { | 890 | if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) { |
881 | printk("DBRI: link_time_slot called on uninitialized pipe\n"); | 891 | printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n"); |
882 | return; | 892 | return; |
883 | } | 893 | } |
884 | 894 | ||
@@ -960,8 +970,8 @@ static void unlink_time_slot(snd_dbri_t * dbri, int pipe, | |||
960 | int val; | 970 | int val; |
961 | 971 | ||
962 | if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) { | 972 | if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) { |
963 | printk | 973 | printk(KERN_ERR |
964 | ("DBRI: unlink_time_slot called with illegal pipe number\n"); | 974 | "DBRI: unlink_time_slot called with illegal pipe number\n"); |
965 | return; | 975 | return; |
966 | } | 976 | } |
967 | 977 | ||
@@ -1001,22 +1011,22 @@ static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data) | |||
1001 | volatile s32 *cmd; | 1011 | volatile s32 *cmd; |
1002 | 1012 | ||
1003 | if (pipe < 16 || pipe > 31) { | 1013 | if (pipe < 16 || pipe > 31) { |
1004 | printk("DBRI: xmit_fixed: Illegal pipe number\n"); | 1014 | printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n"); |
1005 | return; | 1015 | return; |
1006 | } | 1016 | } |
1007 | 1017 | ||
1008 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { | 1018 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { |
1009 | printk("DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe); | 1019 | printk(KERN_ERR "DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe); |
1010 | return; | 1020 | return; |
1011 | } | 1021 | } |
1012 | 1022 | ||
1013 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { | 1023 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { |
1014 | printk("DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe); | 1024 | printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe); |
1015 | return; | 1025 | return; |
1016 | } | 1026 | } |
1017 | 1027 | ||
1018 | if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { | 1028 | if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { |
1019 | printk("DBRI: xmit_fixed: Called on receive pipe %d\n", pipe); | 1029 | printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n", pipe); |
1020 | return; | 1030 | return; |
1021 | } | 1031 | } |
1022 | 1032 | ||
@@ -1036,17 +1046,17 @@ static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data) | |||
1036 | static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr) | 1046 | static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr) |
1037 | { | 1047 | { |
1038 | if (pipe < 16 || pipe > 31) { | 1048 | if (pipe < 16 || pipe > 31) { |
1039 | printk("DBRI: recv_fixed called with illegal pipe number\n"); | 1049 | printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n"); |
1040 | return; | 1050 | return; |
1041 | } | 1051 | } |
1042 | 1052 | ||
1043 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { | 1053 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { |
1044 | printk("DBRI: recv_fixed called on non-fixed pipe %d\n", pipe); | 1054 | printk(KERN_ERR "DBRI: recv_fixed called on non-fixed pipe %d\n", pipe); |
1045 | return; | 1055 | return; |
1046 | } | 1056 | } |
1047 | 1057 | ||
1048 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { | 1058 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { |
1049 | printk("DBRI: recv_fixed called on transmit pipe %d\n", pipe); | 1059 | printk(KERN_ERR "DBRI: recv_fixed called on transmit pipe %d\n", pipe); |
1050 | return; | 1060 | return; |
1051 | } | 1061 | } |
1052 | 1062 | ||
@@ -1075,12 +1085,12 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
1075 | int last_desc = -1; | 1085 | int last_desc = -1; |
1076 | 1086 | ||
1077 | if (info->pipe < 0 || info->pipe > 15) { | 1087 | if (info->pipe < 0 || info->pipe > 15) { |
1078 | printk("DBRI: setup_descs: Illegal pipe number\n"); | 1088 | printk(KERN_ERR "DBRI: setup_descs: Illegal pipe number\n"); |
1079 | return -2; | 1089 | return -2; |
1080 | } | 1090 | } |
1081 | 1091 | ||
1082 | if (dbri->pipes[info->pipe].sdp == 0) { | 1092 | if (dbri->pipes[info->pipe].sdp == 0) { |
1083 | printk("DBRI: setup_descs: Uninitialized pipe %d\n", | 1093 | printk(KERN_ERR "DBRI: setup_descs: Uninitialized pipe %d\n", |
1084 | info->pipe); | 1094 | info->pipe); |
1085 | return -2; | 1095 | return -2; |
1086 | } | 1096 | } |
@@ -1090,20 +1100,20 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
1090 | 1100 | ||
1091 | if (streamno == DBRI_PLAY) { | 1101 | if (streamno == DBRI_PLAY) { |
1092 | if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { | 1102 | if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { |
1093 | printk("DBRI: setup_descs: Called on receive pipe %d\n", | 1103 | printk(KERN_ERR "DBRI: setup_descs: Called on receive pipe %d\n", |
1094 | info->pipe); | 1104 | info->pipe); |
1095 | return -2; | 1105 | return -2; |
1096 | } | 1106 | } |
1097 | } else { | 1107 | } else { |
1098 | if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { | 1108 | if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { |
1099 | printk | 1109 | printk(KERN_ERR |
1100 | ("DBRI: setup_descs: Called on transmit pipe %d\n", | 1110 | "DBRI: setup_descs: Called on transmit pipe %d\n", |
1101 | info->pipe); | 1111 | info->pipe); |
1102 | return -2; | 1112 | return -2; |
1103 | } | 1113 | } |
1104 | /* Should be able to queue multiple buffers to receive on a pipe */ | 1114 | /* Should be able to queue multiple buffers to receive on a pipe */ |
1105 | if (pipe_active(dbri, info->pipe)) { | 1115 | if (pipe_active(dbri, info->pipe)) { |
1106 | printk("DBRI: recv_on_pipe: Called on active pipe %d\n", | 1116 | printk(KERN_ERR "DBRI: recv_on_pipe: Called on active pipe %d\n", |
1107 | info->pipe); | 1117 | info->pipe); |
1108 | return -2; | 1118 | return -2; |
1109 | } | 1119 | } |
@@ -1120,7 +1130,7 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
1120 | break; | 1130 | break; |
1121 | } | 1131 | } |
1122 | if (desc == DBRI_NO_DESCS) { | 1132 | if (desc == DBRI_NO_DESCS) { |
1123 | printk("DBRI: setup_descs: No descriptors\n"); | 1133 | printk(KERN_ERR "DBRI: setup_descs: No descriptors\n"); |
1124 | return -1; | 1134 | return -1; |
1125 | } | 1135 | } |
1126 | 1136 | ||
@@ -1165,7 +1175,7 @@ static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | |||
1165 | } | 1175 | } |
1166 | 1176 | ||
1167 | if (first_desc == -1 || last_desc == -1) { | 1177 | if (first_desc == -1 || last_desc == -1) { |
1168 | printk("DBRI: setup_descs: Not enough descriptors available\n"); | 1178 | printk(KERN_ERR "DBRI: setup_descs: Not enough descriptors available\n"); |
1169 | return -1; | 1179 | return -1; |
1170 | } | 1180 | } |
1171 | 1181 | ||
@@ -1270,7 +1280,7 @@ static void reset_chi(snd_dbri_t * dbri, enum master_or_slave master_or_slave, | |||
1270 | int divisor = 12288 / clockrate; | 1280 | int divisor = 12288 / clockrate; |
1271 | 1281 | ||
1272 | if (divisor > 255 || divisor * clockrate != 12288) | 1282 | if (divisor > 255 || divisor * clockrate != 12288) |
1273 | printk("DBRI: illegal bits_per_frame in setup_chi\n"); | 1283 | printk(KERN_ERR "DBRI: illegal bits_per_frame in setup_chi\n"); |
1274 | 1284 | ||
1275 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD | 1285 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD |
1276 | | D_CHI_BPF(bits_per_frame)); | 1286 | | D_CHI_BPF(bits_per_frame)); |
@@ -1474,7 +1484,6 @@ static int cs4215_setctrl(snd_dbri_t * dbri) | |||
1474 | /* Temporarily mute outputs, and wait 1/8000 sec (125 us) | 1484 | /* Temporarily mute outputs, and wait 1/8000 sec (125 us) |
1475 | * to make sure this takes. This avoids clicking noises. | 1485 | * to make sure this takes. This avoids clicking noises. |
1476 | */ | 1486 | */ |
1477 | |||
1478 | cs4215_setdata(dbri, 1); | 1487 | cs4215_setdata(dbri, 1); |
1479 | udelay(125); | 1488 | udelay(125); |
1480 | 1489 | ||
@@ -1530,8 +1539,8 @@ static int cs4215_setctrl(snd_dbri_t * dbri) | |||
1530 | tmp |= D_C; /* Enable CHI */ | 1539 | tmp |= D_C; /* Enable CHI */ |
1531 | sbus_writel(tmp, dbri->regs + REG0); | 1540 | sbus_writel(tmp, dbri->regs + REG0); |
1532 | 1541 | ||
1533 | for (i = 64; ((dbri->mm.status & 0xe4) != 0x20); --i) { | 1542 | for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) { |
1534 | udelay(125); | 1543 | msleep_interruptible(1); |
1535 | } | 1544 | } |
1536 | if (i == 0) { | 1545 | if (i == 0) { |
1537 | dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", | 1546 | dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", |
@@ -1678,8 +1687,8 @@ buffer and calls dbri_process_one_interrupt() for each interrupt word. | |||
1678 | Complicated interrupts are handled by dedicated functions (which | 1687 | Complicated interrupts are handled by dedicated functions (which |
1679 | appear first in this file). Any pending interrupts can be serviced by | 1688 | appear first in this file). Any pending interrupts can be serviced by |
1680 | calling dbri_process_interrupt_buffer(), which works even if the CPU's | 1689 | calling dbri_process_interrupt_buffer(), which works even if the CPU's |
1681 | interrupts are disabled. This function is used by dbri_cmdsend() | 1690 | interrupts are disabled. This function is used by dbri_cmdlock() |
1682 | to make sure we're synced up with the chip after each command sequence, | 1691 | to make sure we're synced up with the chip before each command sequence, |
1683 | even if we're running cli'ed. | 1692 | even if we're running cli'ed. |
1684 | 1693 | ||
1685 | */ | 1694 | */ |
@@ -1765,11 +1774,13 @@ DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0); | |||
1765 | * Called by main interrupt handler when DBRI signals transmission complete | 1774 | * Called by main interrupt handler when DBRI signals transmission complete |
1766 | * on a pipe (interrupt triggered by the B bit in a transmit descriptor). | 1775 | * on a pipe (interrupt triggered by the B bit in a transmit descriptor). |
1767 | * | 1776 | * |
1768 | * Walks through the pipe's list of transmit buffer descriptors, releasing | 1777 | * Walks through the pipe's list of transmit buffer descriptors and marks |
1769 | * each one's DMA buffer (if present), flagging the descriptor available, | 1778 | * them as available. Stops when the first descriptor is found without |
1770 | * and signaling its callback routine (if present), before proceeding | ||
1771 | * to the next one. Stops when the first descriptor is found without | ||
1772 | * TBC (Transmit Buffer Complete) set, or we've run through them all. | 1779 | * TBC (Transmit Buffer Complete) set, or we've run through them all. |
1780 | * | ||
1781 | * The DMA buffers are not released, but re-used. Since the transmit buffer | ||
1782 | * descriptors are not clobbered, they can be re-submitted as is. This is | ||
1783 | * done by the xmit_descs() tasklet above since that could take longer. | ||
1773 | */ | 1784 | */ |
1774 | 1785 | ||
1775 | static void transmission_complete_intr(snd_dbri_t * dbri, int pipe) | 1786 | static void transmission_complete_intr(snd_dbri_t * dbri, int pipe) |
@@ -1885,7 +1896,11 @@ static void dbri_process_one_interrupt(snd_dbri_t * dbri, int x) | |||
1885 | } | 1896 | } |
1886 | 1897 | ||
1887 | if (channel == D_INTR_CMD && command == D_WAIT) { | 1898 | if (channel == D_INTR_CMD && command == D_WAIT) { |
1888 | dbri->wait_seen++; | 1899 | dbri->wait_ackd = val; |
1900 | if (dbri->wait_send != val) { | ||
1901 | printk(KERN_ERR "Processing wait command %d when %d was send.\n", | ||
1902 | val, dbri->wait_send); | ||
1903 | } | ||
1889 | return; | 1904 | return; |
1890 | } | 1905 | } |
1891 | 1906 | ||
@@ -1994,8 +2009,7 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id, | |||
1994 | * The only one I've seen is MRR, which will be triggered | 2009 | * The only one I've seen is MRR, which will be triggered |
1995 | * if you let a transmit pipe underrun, then try to CDP it. | 2010 | * if you let a transmit pipe underrun, then try to CDP it. |
1996 | * | 2011 | * |
1997 | * If these things persist, we should probably reset | 2012 | * If these things persist, we reset the chip. |
1998 | * and re-init the chip. | ||
1999 | */ | 2013 | */ |
2000 | if ((++errcnt) % 10 == 0) { | 2014 | if ((++errcnt) % 10 == 0) { |
2001 | dprintk(D_INT, "Interrupt errors exceeded.\n"); | 2015 | dprintk(D_INT, "Interrupt errors exceeded.\n"); |
@@ -2094,7 +2108,7 @@ static int snd_dbri_hw_params(snd_pcm_substream_t * substream, | |||
2094 | 2108 | ||
2095 | if ((ret = snd_pcm_lib_malloc_pages(substream, | 2109 | if ((ret = snd_pcm_lib_malloc_pages(substream, |
2096 | params_buffer_bytes(hw_params))) < 0) { | 2110 | params_buffer_bytes(hw_params))) < 0) { |
2097 | snd_printk(KERN_ERR "malloc_pages failed with %d\n", ret); | 2111 | printk(KERN_ERR "malloc_pages failed with %d\n", ret); |
2098 | return ret; | 2112 | return ret; |
2099 | } | 2113 | } |
2100 | 2114 | ||
@@ -2455,8 +2469,7 @@ static int __init snd_dbri_mixer(snd_dbri_t * dbri) | |||
2455 | 2469 | ||
2456 | for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) { | 2470 | for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) { |
2457 | if ((err = snd_ctl_add(card, | 2471 | if ((err = snd_ctl_add(card, |
2458 | snd_ctl_new1(&dbri_controls[idx], | 2472 | snd_ctl_new1(&dbri_controls[idx], dbri))) < 0) |
2459 | dbri))) < 0) | ||
2460 | return err; | 2473 | return err; |
2461 | } | 2474 | } |
2462 | 2475 | ||
@@ -2490,8 +2503,6 @@ static void dbri_debug_read(snd_info_entry_t * entry, | |||
2490 | int pipe; | 2503 | int pipe; |
2491 | snd_iprintf(buffer, "debug=%d\n", dbri_debug); | 2504 | snd_iprintf(buffer, "debug=%d\n", dbri_debug); |
2492 | 2505 | ||
2493 | snd_iprintf(buffer, "CHI pipe in=%d, out=%d\n", | ||
2494 | dbri->chi_in_pipe, dbri->chi_out_pipe); | ||
2495 | for (pipe = 0; pipe < 32; pipe++) { | 2506 | for (pipe = 0; pipe < 32; pipe++) { |
2496 | if (pipe_active(dbri, pipe)) { | 2507 | if (pipe_active(dbri, pipe)) { |
2497 | struct dbri_pipe *pptr = &dbri->pipes[pipe]; | 2508 | struct dbri_pipe *pptr = &dbri->pipes[pipe]; |
@@ -2506,18 +2517,6 @@ static void dbri_debug_read(snd_info_entry_t * entry, | |||
2506 | } | 2517 | } |
2507 | } | 2518 | } |
2508 | } | 2519 | } |
2509 | |||
2510 | static void dbri_debug_write(snd_info_entry_t * entry, | ||
2511 | snd_info_buffer_t * buffer) | ||
2512 | { | ||
2513 | char line[80]; | ||
2514 | int i; | ||
2515 | |||
2516 | if (snd_info_get_line(buffer, line, 80) == 0) { | ||
2517 | sscanf(line, "%d\n", &i); | ||
2518 | dbri_debug = i & 0x3f; | ||
2519 | } | ||
2520 | } | ||
2521 | #endif | 2520 | #endif |
2522 | 2521 | ||
2523 | void snd_dbri_proc(snd_dbri_t * dbri) | 2522 | void snd_dbri_proc(snd_dbri_t * dbri) |
@@ -2531,9 +2530,7 @@ void snd_dbri_proc(snd_dbri_t * dbri) | |||
2531 | #ifdef DBRI_DEBUG | 2530 | #ifdef DBRI_DEBUG |
2532 | err = snd_card_proc_new(dbri->card, "debug", &entry); | 2531 | err = snd_card_proc_new(dbri->card, "debug", &entry); |
2533 | snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); | 2532 | snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); |
2534 | entry->mode = S_IFREG | S_IRUGO | S_IWUSR; /* Writable for root */ | 2533 | entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ |
2535 | entry->c.text.write_size = 256; | ||
2536 | entry->c.text.write = dbri_debug_write; | ||
2537 | #endif | 2534 | #endif |
2538 | } | 2535 | } |
2539 | 2536 | ||
@@ -2637,7 +2634,11 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
2637 | return -ENOENT; | 2634 | return -ENOENT; |
2638 | } | 2635 | } |
2639 | 2636 | ||
2640 | prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); | 2637 | err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); |
2638 | if (err < 0) { | ||
2639 | printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n", dev); | ||
2640 | return -ENODEV; | ||
2641 | } | ||
2641 | 2642 | ||
2642 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | 2643 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, |
2643 | sizeof(snd_dbri_t)); | 2644 | sizeof(snd_dbri_t)); |