Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, platforms: Remove SGI Visual Workstation

The SGI Visual Workstation seems to be dead; remove support so we
don't have to continue maintaining it.

Cc: Andrey Panin <pazke@donpac.ru>
Cc: Michael Reed <mdr@sgi.com>
Link: http://lkml.kernel.org/r/530CFD6C.7040705@zytor.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>

+5 -6454
-2
Documentation/00-INDEX
··· 401 401 - how to set up Linux with a serial line console as the default. 402 402 sgi-ioc4.txt 403 403 - description of the SGI IOC4 PCI (multi function) device. 404 - sgi-visws.txt 405 - - short blurb on the SGI Visual Workstations. 406 404 sh/ 407 405 - directory with info on porting Linux to a new architecture. 408 406 smsc_ece1099.txt
-13
Documentation/sgi-visws.txt
··· 1 - 2 - The SGI Visual Workstations (models 320 and 540) are based around 3 - the Cobalt, Lithium, and Arsenic ASICs. The Cobalt ASIC is the 4 - main system ASIC which interfaces the 1-4 IA32 cpus, the memory 5 - system, and the I/O system in the Lithium ASIC. The Cobalt ASIC 6 - also contains the 3D gfx rendering engine which renders to main 7 - system memory -- part of which is used as the frame buffer which 8 - is DMA'ed to a video connector using the Arsenic ASIC. A PIIX4 9 - chip and NS87307 are used to provide legacy device support (IDE, 10 - serial, floppy, and parallel). 11 - 12 - The Visual Workstation chipset largely conforms to the PC architecture 13 - with some notable exceptions such as interrupt handling.
-293
Documentation/sound/oss/vwsnd
··· 1 - vwsnd - Sound driver for the Silicon Graphics 320 and 540 Visual 2 - Workstations' onboard audio. 3 - 4 - Copyright 1999 Silicon Graphics, Inc. All rights reserved. 5 - 6 - 7 - At the time of this writing, March 1999, there are two models of 8 - Visual Workstation, the 320 and the 540. This document only describes 9 - those models. Future Visual Workstation models may have different 10 - sound capabilities, and this driver will probably not work on those 11 - boxes. 12 - 13 - The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio 14 - codec chip. The AD1843 is accessed through the Cobalt I/O ASIC, also 15 - known as Lithium. This driver programs both chips. 16 - 17 - ============================================================================== 18 - QUICK CONFIGURATION 19 - 20 - # insmod soundcore 21 - # insmod vwsnd 22 - 23 - ============================================================================== 24 - I/O CONNECTIONS 25 - 26 - On the Visual Workstation, only three of the AD1843 inputs are hooked 27 - up. The analog line in jacks are connected to the AD1843's AUX1 28 - input. The CD audio lines are connected to the AD1843's AUX2 input. 29 - The microphone jack is connected to the AD1843's MIC input. The mic 30 - jack is mono, but the signal is delivered to both the left and right 31 - MIC inputs. You can record in stereo from the mic input, but you will 32 - get the same signal on both channels (within the limits of A/D 33 - accuracy). Full scale on the Line input is +/- 2.0 V. Full scale on 34 - the MIC input is 20 dB less, or +/- 0.2 V. 35 - 36 - The AD1843's LOUT1 outputs are connected to the Line Out jacks. The 37 - AD1843's HPOUT outputs are connected to the speaker/headphone jack. 38 - LOUT2 is not connected. Line out's maximum level is +/- 2.0 V peak to 39 - peak. The speaker/headphone out's maximum is +/- 4.0 V peak to peak. 40 - 41 - The AD1843's PCM input channel and one of its output channels (DAC1) 42 - are connected to Lithium. The other output channel (DAC2) is not 43 - connected. 44 - 45 - ============================================================================== 46 - CAPABILITIES 47 - 48 - The AD1843 has PCM input and output (Pulse Code Modulation, also known 49 - as wavetable). PCM input and output can be mono or stereo in any of 50 - four formats. The formats are 16 bit signed and 8 bit unsigned, 51 - u-Law, and A-Law format. Any sample rate from 4 KHz to 49 KHz is 52 - available, in 1 Hz increments. 53 - 54 - The AD1843 includes an analog mixer that can mix all three input 55 - signals (line, mic and CD) into the analog outputs. The mixer has a 56 - separate gain control and mute switch for each input. 57 - 58 - There are two outputs, line out and speaker/headphone out. They 59 - always produce the same signal, and the speaker always has 3 dB more 60 - gain than the line out. The speaker/headphone output can be muted, 61 - but this driver does not export that function. 62 - 63 - The hardware can sync audio to the video clock, but this driver does 64 - not have a way to specify syncing to video. 65 - 66 - ============================================================================== 67 - PROGRAMMING 68 - 69 - This section explains the API supported by the driver. Also see the 70 - Open Sound Programming Guide at http://www.opensound.com/pguide/ . 71 - This section assumes familiarity with that document. 72 - 73 - The driver has two interfaces, an I/O interface and a mixer interface. 74 - There is no MIDI or sequencer capability. 75 - 76 - ============================================================================== 77 - PROGRAMMING PCM I/O 78 - 79 - The I/O interface is usually accessed as /dev/audio or /dev/dsp. 80 - Using the standard Open Sound System (OSS) ioctl calls, the sample 81 - rate, number of channels, and sample format may be set within the 82 - limitations described above. The driver supports triggering. It also 83 - supports getting the input and output pointers with one-sample 84 - accuracy. 85 - 86 - The SNDCTL_DSP_GETCAP ioctl returns these capabilities. 87 - 88 - DSP_CAP_DUPLEX - driver supports full duplex. 89 - 90 - DSP_CAP_TRIGGER - driver supports triggering. 91 - 92 - DSP_CAP_REALTIME - values returned by SNDCTL_DSP_GETIPTR 93 - and SNDCTL_DSP_GETOPTR are accurate to a few samples. 94 - 95 - Memory mapping (mmap) is not implemented. 96 - 97 - The driver permits subdivided fragment sizes from 64 to 4096 bytes. 98 - The number of fragments can be anything from 3 fragments to however 99 - many fragments fit into 124 kilobytes. It is up to the user to 100 - determine how few/small fragments can be used without introducing 101 - glitches with a given workload. Linux is not realtime, so we can't 102 - promise anything. (sigh...) 103 - 104 - When this driver is switched into or out of mu-Law or A-Law mode on 105 - output, it may produce an audible click. This is unavoidable. To 106 - prevent clicking, use signed 16-bit mode instead, and convert from 107 - mu-Law or A-Law format in software. 108 - 109 - ============================================================================== 110 - PROGRAMMING THE MIXER INTERFACE 111 - 112 - The mixer interface is usually accessed as /dev/mixer. It is accessed 113 - through ioctls. The mixer allows the application to control gain or 114 - mute several audio signal paths, and also allows selection of the 115 - recording source. 116 - 117 - Each of the constants described here can be read using the 118 - MIXER_READ(SOUND_MIXER_xxx) ioctl. Those that are not read-only can 119 - also be written using the MIXER_WRITE(SOUND_MIXER_xxx) ioctl. In most 120 - cases, <sys/soundcard.h> defines constants SOUND_MIXER_READ_xxx and 121 - SOUND_MIXER_WRITE_xxx which work just as well. 122 - 123 - SOUND_MIXER_CAPS Read-only 124 - 125 - This is a mask of optional driver capabilities that are implemented. 126 - This driver's only capability is SOUND_CAP_EXCL_INPUT, which means 127 - that only one recording source can be active at a time. 128 - 129 - SOUND_MIXER_DEVMASK Read-only 130 - 131 - This is a mask of the sound channels. This driver's channels are PCM, 132 - LINE, MIC, CD, and RECLEV. 133 - 134 - SOUND_MIXER_STEREODEVS Read-only 135 - 136 - This is a mask of which sound channels are capable of stereo. All 137 - channels are capable of stereo. (But see caveat on MIC input in I/O 138 - CONNECTIONS section above). 139 - 140 - SOUND_MIXER_OUTMASK Read-only 141 - 142 - This is a mask of channels that route inputs through to outputs. 143 - Those are LINE, MIC, and CD. 144 - 145 - SOUND_MIXER_RECMASK Read-only 146 - 147 - This is a mask of channels that can be recording sources. Those are 148 - PCM, LINE, MIC, CD. 149 - 150 - SOUND_MIXER_PCM Default: 0x5757 (0 dB) 151 - 152 - This is the gain control for PCM output. The left and right channel 153 - gain are controlled independently. This gain control has 64 levels, 154 - which range from -82.5 dB to +12.0 dB in 1.5 dB steps. Those 64 155 - levels are mapped onto 100 levels at the ioctl, see below. 156 - 157 - SOUND_MIXER_LINE Default: 0x4a4a (0 dB) 158 - 159 - This is the gain control for mixing the Line In source into the 160 - outputs. The left and right channel gain are controlled 161 - independently. This gain control has 32 levels, which range from 162 - -34.5 dB to +12.0 dB in 1.5 dB steps. Those 32 levels are mapped onto 163 - 100 levels at the ioctl, see below. 164 - 165 - SOUND_MIXER_MIC Default: 0x4a4a (0 dB) 166 - 167 - This is the gain control for mixing the MIC source into the outputs. 168 - The left and right channel gain are controlled independently. This 169 - gain control has 32 levels, which range from -34.5 dB to +12.0 dB in 170 - 1.5 dB steps. Those 32 levels are mapped onto 100 levels at the 171 - ioctl, see below. 172 - 173 - SOUND_MIXER_CD Default: 0x4a4a (0 dB) 174 - 175 - This is the gain control for mixing the CD audio source into the 176 - outputs. The left and right channel gain are controlled 177 - independently. This gain control has 32 levels, which range from 178 - -34.5 dB to +12.0 dB in 1.5 dB steps. Those 32 levels are mapped onto 179 - 100 levels at the ioctl, see below. 180 - 181 - SOUND_MIXER_RECLEV Default: 0 (0 dB) 182 - 183 - This is the gain control for PCM input (RECording LEVel). The left 184 - and right channel gain are controlled independently. This gain 185 - control has 16 levels, which range from 0 dB to +22.5 dB in 1.5 dB 186 - steps. Those 16 levels are mapped onto 100 levels at the ioctl, see 187 - below. 188 - 189 - SOUND_MIXER_RECSRC Default: SOUND_MASK_LINE 190 - 191 - This is a mask of currently selected PCM input sources (RECording 192 - SouRCes). Because the AD1843 can only have a single recording source 193 - at a time, only one bit at a time can be set in this mask. The 194 - allowable values are SOUND_MASK_PCM, SOUND_MASK_LINE, SOUND_MASK_MIC, 195 - or SOUND_MASK_CD. Selecting SOUND_MASK_PCM sets up internal 196 - resampling which is useful for loopback testing and for hardware 197 - sample rate conversion. But software sample rate conversion is 198 - probably faster, so I don't know how useful that is. 199 - 200 - SOUND_MIXER_OUTSRC DEFAULT: SOUND_MASK_LINE|SOUND_MASK_MIC|SOUND_MASK_CD 201 - 202 - This is a mask of sources that are currently passed through to the 203 - outputs. Those sources whose bits are not set are muted. 204 - 205 - ============================================================================== 206 - GAIN CONTROL 207 - 208 - There are five gain controls listed above. Each has 16, 32, or 64 209 - steps. Each control has 1.5 dB of gain per step. Each control is 210 - stereo. 211 - 212 - The OSS defines the argument to a channel gain ioctl as having two 213 - components, left and right, each of which ranges from 0 to 100. The 214 - two components are packed into the same word, with the left side gain 215 - in the least significant byte, and the right side gain in the second 216 - least significant byte. In C, we would say this. 217 - 218 - #include <assert.h> 219 - 220 - ... 221 - 222 - assert(leftgain >= 0 && leftgain <= 100); 223 - assert(rightgain >= 0 && rightgain <= 100); 224 - arg = leftgain | rightgain << 8; 225 - 226 - So each OSS gain control has 101 steps. But the hardware has 16, 32, 227 - or 64 steps. The hardware steps are spread across the 101 OSS steps 228 - nearly evenly. The conversion formulas are like this, given N equals 229 - 16, 32, or 64. 230 - 231 - int round = N/2 - 1; 232 - OSS_gain_steps = (hw_gain_steps * 100 + round) / (N - 1); 233 - hw_gain_steps = (OSS_gain_steps * (N - 1) + round) / 100; 234 - 235 - Here is a snippet of C code that will return the left and right gain 236 - of any channel in dB. Pass it one of the predefined gain_desc_t 237 - structures to access any of the five channels' gains. 238 - 239 - typedef struct gain_desc { 240 - float min_gain; 241 - float gain_step; 242 - int nbits; 243 - int chan; 244 - } gain_desc_t; 245 - 246 - const gain_desc_t gain_pcm = { -82.5, 1.5, 6, SOUND_MIXER_PCM }; 247 - const gain_desc_t gain_line = { -34.5, 1.5, 5, SOUND_MIXER_LINE }; 248 - const gain_desc_t gain_mic = { -34.5, 1.5, 5, SOUND_MIXER_MIC }; 249 - const gain_desc_t gain_cd = { -34.5, 1.5, 5, SOUND_MIXER_CD }; 250 - const gain_desc_t gain_reclev = { 0.0, 1.5, 4, SOUND_MIXER_RECLEV }; 251 - 252 - int get_gain_dB(int fd, const gain_desc_t *gp, 253 - float *left, float *right) 254 - { 255 - int word; 256 - int lg, rg; 257 - int mask = (1 << gp->nbits) - 1; 258 - 259 - if (ioctl(fd, MIXER_READ(gp->chan), &word) != 0) 260 - return -1; /* fail */ 261 - lg = word & 0xFF; 262 - rg = word >> 8 & 0xFF; 263 - lg = (lg * mask + mask / 2) / 100; 264 - rg = (rg * mask + mask / 2) / 100; 265 - *left = gp->min_gain + gp->gain_step * lg; 266 - *right = gp->min_gain + gp->gain_step * rg; 267 - return 0; 268 - } 269 - 270 - And here is the corresponding routine to set a channel's gain in dB. 271 - 272 - int set_gain_dB(int fd, const gain_desc_t *gp, float left, float right) 273 - { 274 - float max_gain = 275 - gp->min_gain + (1 << gp->nbits) * gp->gain_step; 276 - float round = gp->gain_step / 2; 277 - int mask = (1 << gp->nbits) - 1; 278 - int word; 279 - int lg, rg; 280 - 281 - if (left < gp->min_gain || right < gp->min_gain) 282 - return EINVAL; 283 - lg = (left - gp->min_gain + round) / gp->gain_step; 284 - rg = (right - gp->min_gain + round) / gp->gain_step; 285 - if (lg >= (1 << gp->nbits) || rg >= (1 << gp->nbits)) 286 - return EINVAL; 287 - lg = (100 * lg + mask / 2) / mask; 288 - rg = (100 * rg + mask / 2) / mask; 289 - word = lg | rg << 8; 290 - 291 - return ioctl(fd, MIXER_WRITE(gp->chan), &word); 292 - } 293 -
-7
MAINTAINERS
··· 7757 7757 F: drivers/tty/serial/ioc?_serial.c 7758 7758 F: include/linux/ioc?.h 7759 7759 7760 - SGI VISUAL WORKSTATION 320 AND 540 7761 - M: Andrey Panin <pazke@donpac.ru> 7762 - L: linux-visws-devel@lists.sf.net 7763 - W: http://linux-visws.sf.net 7764 - S: Maintained for 2.6. 7765 - F: Documentation/sgi-visws.txt 7766 - 7767 7760 SGI XP/XPC/XPNET DRIVER 7768 7761 M: Cliff Whickman <cpw@sgi.com> 7769 7762 M: Robin Holt <robinmholt@gmail.com>
-17
arch/x86/Kconfig
··· 517 517 depends on X86_64 || !SPARSEMEM 518 518 select ARCH_SUPPORTS_MEMORY_FAILURE 519 519 520 - config X86_VISWS 521 - bool "SGI 320/540 (Visual Workstation)" 522 - depends on X86_32 && PCI && X86_MPPARSE && PCI_GODIRECT 523 - depends on X86_32_NON_STANDARD 524 - ---help--- 525 - The SGI Visual Workstation series is an IA32-based workstation 526 - based on SGI systems chips with some legacy PC hardware attached. 527 - 528 - Say Y here to create a kernel to run on the SGI 320 or 540. 529 - 530 - A kernel compiled for the Visual Workstation will run on general 531 - PCs as well. See <file:Documentation/sgi-visws.txt> for details. 532 - 533 520 config STA2X11 534 521 bool "STA2X11 Companion Chip Support" 535 522 depends on X86_32_NON_STANDARD && PCI ··· 846 859 config X86_IO_APIC 847 860 def_bool y 848 861 depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC || PCI_MSI 849 - 850 - config X86_VISWS_APIC 851 - def_bool y 852 - depends on X86_32 && X86_VISWS 853 862 854 863 config X86_REROUTE_FOR_BROKEN_BOOT_IRQS 855 864 bool "Reroute for broken boot IRQs"
-6
arch/x86/include/asm/fixmap.h
··· 98 98 FIX_IO_APIC_BASE_0, 99 99 FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, 100 100 #endif 101 - #ifdef CONFIG_X86_VISWS_APIC 102 - FIX_CO_CPU, /* Cobalt timer */ 103 - FIX_CO_APIC, /* Cobalt APIC Redirection Table */ 104 - FIX_LI_PCIA, /* Lithium PCI Bridge A */ 105 - FIX_LI_PCIB, /* Lithium PCI Bridge B */ 106 - #endif 107 101 FIX_RO_IDT, /* Virtual mapping for read-only IDT */ 108 102 #ifdef CONFIG_X86_32 109 103 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
-1
arch/x86/include/asm/hw_irq.h
··· 98 98 #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) 99 99 extern unsigned long io_apic_irqs; 100 100 101 - extern void init_VISWS_APIC_irqs(void); 102 101 extern void setup_IO_APIC(void); 103 102 extern void disable_IO_APIC(void); 104 103
-6
arch/x86/include/asm/setup.h
··· 39 39 40 40 void setup_bios_corruption_check(void); 41 41 42 - #ifdef CONFIG_X86_VISWS 43 - extern void visws_early_detect(void); 44 - #else 45 - static inline void visws_early_detect(void) { } 46 - #endif 47 - 48 42 extern unsigned long saved_video_mode; 49 43 50 44 extern void reserve_standard_io_resources(void);
-127
arch/x86/include/asm/visws/cobalt.h
··· 1 - #ifndef _ASM_X86_VISWS_COBALT_H 2 - #define _ASM_X86_VISWS_COBALT_H 3 - 4 - #include <asm/fixmap.h> 5 - 6 - /* 7 - * Cobalt SGI Visual Workstation system ASIC 8 - */ 9 - 10 - #define CO_CPU_NUM_PHYS 0x1e00 11 - #define CO_CPU_TAB_PHYS (CO_CPU_NUM_PHYS + 2) 12 - 13 - #define CO_CPU_MAX 4 14 - 15 - #define CO_CPU_PHYS 0xc2000000 16 - #define CO_APIC_PHYS 0xc4000000 17 - 18 - /* see set_fixmap() and asm/fixmap.h */ 19 - #define CO_CPU_VADDR (fix_to_virt(FIX_CO_CPU)) 20 - #define CO_APIC_VADDR (fix_to_virt(FIX_CO_APIC)) 21 - 22 - /* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */ 23 - #define CO_CPU_REV 0x08 24 - #define CO_CPU_CTRL 0x10 25 - #define CO_CPU_STAT 0x20 26 - #define CO_CPU_TIMEVAL 0x30 27 - 28 - /* CO_CPU_CTRL bits */ 29 - #define CO_CTRL_TIMERUN 0x04 /* 0 == disabled */ 30 - #define CO_CTRL_TIMEMASK 0x08 /* 0 == unmasked */ 31 - 32 - /* CO_CPU_STATUS bits */ 33 - #define CO_STAT_TIMEINTR 0x02 /* (r) 1 == int pend, (w) 0 == clear */ 34 - 35 - /* CO_CPU_TIMEVAL value */ 36 - #define CO_TIME_HZ 100000000 /* Cobalt core rate */ 37 - 38 - /* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */ 39 - #define CO_APIC_HI(n) (((n) * 0x10) + 4) 40 - #define CO_APIC_LO(n) ((n) * 0x10) 41 - #define CO_APIC_ID 0x0ffc 42 - 43 - /* CO_APIC_ID bits */ 44 - #define CO_APIC_ENABLE 0x00000100 45 - 46 - /* CO_APIC_LO bits */ 47 - #define CO_APIC_MASK 0x00010000 /* 0 = enabled */ 48 - #define CO_APIC_LEVEL 0x00008000 /* 0 = edge */ 49 - 50 - /* 51 - * Where things are physically wired to Cobalt 52 - * #defines with no board _<type>_<rev>_ are common to all (thus far) 53 - */ 54 - #define CO_APIC_IDE0 4 55 - #define CO_APIC_IDE1 2 /* Only on 320 */ 56 - 57 - #define CO_APIC_8259 12 /* serial, floppy, par-l-l */ 58 - 59 - /* Lithium PCI Bridge A -- "the one with 82557 Ethernet" */ 60 - #define CO_APIC_PCIA_BASE0 0 /* and 1 */ /* slot 0, line 0 */ 61 - #define CO_APIC_PCIA_BASE123 5 /* and 6 */ /* slot 0, line 1 */ 62 - 63 - #define CO_APIC_PIIX4_USB 7 /* this one is weird */ 64 - 65 - /* Lithium PCI Bridge B -- "the one with PIIX4" */ 66 - #define CO_APIC_PCIB_BASE0 8 /* and 9-12 *//* slot 0, line 0 */ 67 - #define CO_APIC_PCIB_BASE123 13 /* 14.15 */ /* slot 0, line 1 */ 68 - 69 - #define CO_APIC_VIDOUT0 16 70 - #define CO_APIC_VIDOUT1 17 71 - #define CO_APIC_VIDIN0 18 72 - #define CO_APIC_VIDIN1 19 73 - 74 - #define CO_APIC_LI_AUDIO 22 75 - 76 - #define CO_APIC_AS 24 77 - #define CO_APIC_RE 25 78 - 79 - #define CO_APIC_CPU 28 /* Timer and Cache interrupt */ 80 - #define CO_APIC_NMI 29 81 - #define CO_APIC_LAST CO_APIC_NMI 82 - 83 - /* 84 - * This is how irqs are assigned on the Visual Workstation. 85 - * Legacy devices get irq's 1-15 (system clock is 0 and is CO_APIC_CPU). 86 - * All other devices (including PCI) go to Cobalt and are irq's 16 on up. 87 - */ 88 - #define CO_IRQ_APIC0 16 /* irq of apic entry 0 */ 89 - #define IS_CO_APIC(irq) ((irq) >= CO_IRQ_APIC0) 90 - #define CO_IRQ(apic) (CO_IRQ_APIC0 + (apic)) /* apic ent to irq */ 91 - #define CO_APIC(irq) ((irq) - CO_IRQ_APIC0) /* irq to apic ent */ 92 - #define CO_IRQ_IDE0 14 /* knowledge of... */ 93 - #define CO_IRQ_IDE1 15 /* ... ide driver defaults! */ 94 - #define CO_IRQ_8259 CO_IRQ(CO_APIC_8259) 95 - 96 - #ifdef CONFIG_X86_VISWS_APIC 97 - static inline void co_cpu_write(unsigned long reg, unsigned long v) 98 - { 99 - *((volatile unsigned long *)(CO_CPU_VADDR+reg))=v; 100 - } 101 - 102 - static inline unsigned long co_cpu_read(unsigned long reg) 103 - { 104 - return *((volatile unsigned long *)(CO_CPU_VADDR+reg)); 105 - } 106 - 107 - static inline void co_apic_write(unsigned long reg, unsigned long v) 108 - { 109 - *((volatile unsigned long *)(CO_APIC_VADDR+reg))=v; 110 - } 111 - 112 - static inline unsigned long co_apic_read(unsigned long reg) 113 - { 114 - return *((volatile unsigned long *)(CO_APIC_VADDR+reg)); 115 - } 116 - #endif 117 - 118 - extern char visws_board_type; 119 - 120 - #define VISWS_320 0 121 - #define VISWS_540 1 122 - 123 - extern char visws_board_rev; 124 - 125 - extern int pci_visws_init(void); 126 - 127 - #endif /* _ASM_X86_VISWS_COBALT_H */
-53
arch/x86/include/asm/visws/lithium.h
··· 1 - #ifndef _ASM_X86_VISWS_LITHIUM_H 2 - #define _ASM_X86_VISWS_LITHIUM_H 3 - 4 - #include <asm/fixmap.h> 5 - 6 - /* 7 - * Lithium is the SGI Visual Workstation I/O ASIC 8 - */ 9 - 10 - #define LI_PCI_A_PHYS 0xfc000000 /* Enet is dev 3 */ 11 - #define LI_PCI_B_PHYS 0xfd000000 /* PIIX4 is here */ 12 - 13 - /* see set_fixmap() and asm/fixmap.h */ 14 - #define LI_PCIA_VADDR (fix_to_virt(FIX_LI_PCIA)) 15 - #define LI_PCIB_VADDR (fix_to_virt(FIX_LI_PCIB)) 16 - 17 - /* Not a standard PCI? (not in linux/pci.h) */ 18 - #define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */ 19 - #define LI_PCI_INTEN 0x46 20 - 21 - /* LI_PCI_INTENT bits */ 22 - #define LI_INTA_0 0x0001 23 - #define LI_INTA_1 0x0002 24 - #define LI_INTA_2 0x0004 25 - #define LI_INTA_3 0x0008 26 - #define LI_INTA_4 0x0010 27 - #define LI_INTB 0x0020 28 - #define LI_INTC 0x0040 29 - #define LI_INTD 0x0080 30 - 31 - /* More special purpose macros... */ 32 - static inline void li_pcia_write16(unsigned long reg, unsigned short v) 33 - { 34 - *((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v; 35 - } 36 - 37 - static inline unsigned short li_pcia_read16(unsigned long reg) 38 - { 39 - return *((volatile unsigned short *)(LI_PCIA_VADDR+reg)); 40 - } 41 - 42 - static inline void li_pcib_write16(unsigned long reg, unsigned short v) 43 - { 44 - *((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v; 45 - } 46 - 47 - static inline unsigned short li_pcib_read16(unsigned long reg) 48 - { 49 - return *((volatile unsigned short *)(LI_PCIB_VADDR+reg)); 50 - } 51 - 52 - #endif /* _ASM_X86_VISWS_LITHIUM_H */ 53 -
-107
arch/x86/include/asm/visws/piix4.h
··· 1 - #ifndef _ASM_X86_VISWS_PIIX4_H 2 - #define _ASM_X86_VISWS_PIIX4_H 3 - 4 - /* 5 - * PIIX4 as used on SGI Visual Workstations 6 - */ 7 - 8 - #define PIIX_PM_START 0x0F80 9 - 10 - #define SIO_GPIO_START 0x0FC0 11 - 12 - #define SIO_PM_START 0x0FC8 13 - 14 - #define PMBASE PIIX_PM_START 15 - #define GPIREG0 (PMBASE+0x30) 16 - #define GPIREG(x) (GPIREG0+((x)/8)) 17 - #define GPIBIT(x) (1 << ((x)%8)) 18 - 19 - #define PIIX_GPI_BD_ID1 18 20 - #define PIIX_GPI_BD_ID2 19 21 - #define PIIX_GPI_BD_ID3 20 22 - #define PIIX_GPI_BD_ID4 21 23 - #define PIIX_GPI_BD_REG GPIREG(PIIX_GPI_BD_ID1) 24 - #define PIIX_GPI_BD_MASK (GPIBIT(PIIX_GPI_BD_ID1) | \ 25 - GPIBIT(PIIX_GPI_BD_ID2) | \ 26 - GPIBIT(PIIX_GPI_BD_ID3) | \ 27 - GPIBIT(PIIX_GPI_BD_ID4) ) 28 - 29 - #define PIIX_GPI_BD_SHIFT (PIIX_GPI_BD_ID1 % 8) 30 - 31 - #define SIO_INDEX 0x2e 32 - #define SIO_DATA 0x2f 33 - 34 - #define SIO_DEV_SEL 0x7 35 - #define SIO_DEV_ENB 0x30 36 - #define SIO_DEV_MSB 0x60 37 - #define SIO_DEV_LSB 0x61 38 - 39 - #define SIO_GP_DEV 0x7 40 - 41 - #define SIO_GP_BASE SIO_GPIO_START 42 - #define SIO_GP_MSB (SIO_GP_BASE>>8) 43 - #define SIO_GP_LSB (SIO_GP_BASE&0xff) 44 - 45 - #define SIO_GP_DATA1 (SIO_GP_BASE+0) 46 - 47 - #define SIO_PM_DEV 0x8 48 - 49 - #define SIO_PM_BASE SIO_PM_START 50 - #define SIO_PM_MSB (SIO_PM_BASE>>8) 51 - #define SIO_PM_LSB (SIO_PM_BASE&0xff) 52 - #define SIO_PM_INDEX (SIO_PM_BASE+0) 53 - #define SIO_PM_DATA (SIO_PM_BASE+1) 54 - 55 - #define SIO_PM_FER2 0x1 56 - 57 - #define SIO_PM_GP_EN 0x80 58 - 59 - 60 - 61 - /* 62 - * This is the dev/reg where generating a config cycle will 63 - * result in a PCI special cycle. 64 - */ 65 - #define SPECIAL_DEV 0xff 66 - #define SPECIAL_REG 0x00 67 - 68 - /* 69 - * PIIX4 needs to see a special cycle with the following data 70 - * to be convinced the processor has gone into the stop grant 71 - * state. PIIX4 insists on seeing this before it will power 72 - * down a system. 73 - */ 74 - #define PIIX_SPECIAL_STOP 0x00120002 75 - 76 - #define PIIX4_RESET_PORT 0xcf9 77 - #define PIIX4_RESET_VAL 0x6 78 - 79 - #define PMSTS_PORT 0xf80 // 2 bytes PM Status 80 - #define PMEN_PORT 0xf82 // 2 bytes PM Enable 81 - #define PMCNTRL_PORT 0xf84 // 2 bytes PM Control 82 - 83 - #define PM_SUSPEND_ENABLE 0x2000 // start sequence to suspend state 84 - 85 - /* 86 - * PMSTS and PMEN I/O bit definitions. 87 - * (Bits are the same in both registers) 88 - */ 89 - #define PM_STS_RSM (1<<15) // Resume Status 90 - #define PM_STS_PWRBTNOR (1<<11) // Power Button Override 91 - #define PM_STS_RTC (1<<10) // RTC status 92 - #define PM_STS_PWRBTN (1<<8) // Power Button Pressed? 93 - #define PM_STS_GBL (1<<5) // Global Status 94 - #define PM_STS_BM (1<<4) // Bus Master Status 95 - #define PM_STS_TMROF (1<<0) // Timer Overflow Status. 96 - 97 - /* 98 - * Stop clock GPI register 99 - */ 100 - #define PIIX_GPIREG0 (0xf80 + 0x30) 101 - 102 - /* 103 - * Stop clock GPI bit in GPIREG0 104 - */ 105 - #define PIIX_GPI_STPCLK 0x4 // STPCLK signal routed back in 106 - 107 - #endif /* _ASM_X86_VISWS_PIIX4_H */
-5
arch/x86/include/asm/visws/sgivw.h
··· 1 - /* 2 - * Frame buffer position and size: 3 - */ 4 - extern unsigned long sgivwfb_mem_phys; 5 - extern unsigned long sgivwfb_mem_size;
-1
arch/x86/kernel/apic/apic.c
··· 2132 2132 * 2133 2133 * - arch/x86/kernel/mpparse.c: MP_processor_info() 2134 2134 * - arch/x86/mm/amdtopology.c: amd_numa_init() 2135 - * - arch/x86/platform/visws/visws_quirks.c: MP_processor_info() 2136 2135 * 2137 2136 * This function is executed with the modified 2138 2137 * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel
-1
arch/x86/kernel/setup.c
··· 869 869 870 870 #ifdef CONFIG_X86_32 871 871 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); 872 - visws_early_detect(); 873 872 874 873 /* 875 874 * copy kernel address range established so far and switch
-2
arch/x86/pci/Makefile
··· 13 13 14 14 obj-$(CONFIG_STA2X11) += sta2x11-fixup.o 15 15 16 - obj-$(CONFIG_X86_VISWS) += visws.o 17 - 18 16 obj-$(CONFIG_X86_NUMAQ) += numaq_32.o 19 17 obj-$(CONFIG_X86_NUMACHIP) += numachip.o 20 18
+1 -4
arch/x86/pci/common.c
··· 561 561 pci_probe |= PCI_PROBE_NOEARLY; 562 562 return NULL; 563 563 } 564 - #ifndef CONFIG_X86_VISWS 565 564 else if (!strcmp(str, "usepirqmask")) { 566 565 pci_probe |= PCI_USE_PIRQ_MASK; 567 566 return NULL; ··· 570 571 } else if (!strncmp(str, "lastbus=", 8)) { 571 572 pcibios_last_bus = simple_strtol(str+8, NULL, 0); 572 573 return NULL; 573 - } 574 - #endif 575 - else if (!strcmp(str, "rom")) { 574 + } else if (!strcmp(str, "rom")) { 576 575 pci_probe |= PCI_ASSIGN_ROMS; 577 576 return NULL; 578 577 } else if (!strcmp(str, "norom")) {
-87
arch/x86/pci/visws.c
··· 1 - /* 2 - * Low-Level PCI Support for SGI Visual Workstation 3 - * 4 - * (c) 1999--2000 Martin Mares <mj@ucw.cz> 5 - */ 6 - 7 - #include <linux/kernel.h> 8 - #include <linux/pci.h> 9 - #include <linux/init.h> 10 - 11 - #include <asm/setup.h> 12 - #include <asm/pci_x86.h> 13 - #include <asm/visws/cobalt.h> 14 - #include <asm/visws/lithium.h> 15 - 16 - static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } 17 - static void pci_visws_disable_irq(struct pci_dev *dev) { } 18 - 19 - /* int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; */ 20 - /* void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; */ 21 - 22 - /* void __init pcibios_penalize_isa_irq(int irq, int active) {} */ 23 - 24 - 25 - unsigned int pci_bus0, pci_bus1; 26 - 27 - static int __init visws_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 28 - { 29 - int irq, bus = dev->bus->number; 30 - 31 - pin--; 32 - 33 - /* Nothing useful at PIIX4 pin 1 */ 34 - if (bus == pci_bus0 && slot == 4 && pin == 0) 35 - return -1; 36 - 37 - /* PIIX4 USB is on Bus 0, Slot 4, Line 3 */ 38 - if (bus == pci_bus0 && slot == 4 && pin == 3) { 39 - irq = CO_IRQ(CO_APIC_PIIX4_USB); 40 - goto out; 41 - } 42 - 43 - /* First pin spread down 1 APIC entry per slot */ 44 - if (pin == 0) { 45 - irq = CO_IRQ((bus == pci_bus0 ? CO_APIC_PCIB_BASE0 : 46 - CO_APIC_PCIA_BASE0) + slot); 47 - goto out; 48 - } 49 - 50 - /* lines 1,2,3 from any slot is shared in this twirly pattern */ 51 - if (bus == pci_bus1) { 52 - /* lines 1-3 from devices 0 1 rotate over 2 apic entries */ 53 - irq = CO_IRQ(CO_APIC_PCIA_BASE123 + ((slot + (pin - 1)) % 2)); 54 - } else { /* bus == pci_bus0 */ 55 - /* lines 1-3 from devices 0-3 rotate over 3 apic entries */ 56 - if (slot == 0) 57 - slot = 3; /* same pattern */ 58 - irq = CO_IRQ(CO_APIC_PCIA_BASE123 + ((3 - slot) + (pin - 1) % 3)); 59 - } 60 - out: 61 - printk(KERN_DEBUG "PCI: Bus %d Slot %d Line %d -> IRQ %d\n", bus, slot, pin, irq); 62 - return irq; 63 - } 64 - 65 - int __init pci_visws_init(void) 66 - { 67 - pcibios_enable_irq = &pci_visws_enable_irq; 68 - pcibios_disable_irq = &pci_visws_disable_irq; 69 - 70 - /* The VISWS supports configuration access type 1 only */ 71 - pci_probe = (pci_probe | PCI_PROBE_CONF1) & 72 - ~(PCI_PROBE_BIOS | PCI_PROBE_CONF2); 73 - 74 - pci_bus0 = li_pcib_read16(LI_PCI_BUSNUM) & 0xff; 75 - pci_bus1 = li_pcia_read16(LI_PCI_BUSNUM) & 0xff; 76 - 77 - printk(KERN_INFO "PCI: Lithium bridge A bus: %u, " 78 - "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0); 79 - 80 - raw_pci_ops = &pci_direct_conf1; 81 - pci_scan_bus_with_sysdata(pci_bus0); 82 - pci_scan_bus_with_sysdata(pci_bus1); 83 - pci_fixup_irqs(pci_common_swizzle, visws_map_irq); 84 - pcibios_resource_survey(); 85 - /* Request bus scan */ 86 - return 1; 87 - }
-1
arch/x86/platform/Makefile
··· 9 9 obj-y += scx200/ 10 10 obj-y += sfi/ 11 11 obj-y += ts5500/ 12 - obj-y += visws/ 13 12 obj-y += uv/
-1
arch/x86/platform/visws/Makefile
··· 1 - obj-$(CONFIG_X86_VISWS) += visws_quirks.o
-608
arch/x86/platform/visws/visws_quirks.c
··· 1 - /* 2 - * SGI Visual Workstation support and quirks, unmaintained. 3 - * 4 - * Split out from setup.c by davej@suse.de 5 - * 6 - * Copyright (C) 1999 Bent Hagemark, Ingo Molnar 7 - * 8 - * SGI Visual Workstation interrupt controller 9 - * 10 - * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC 11 - * which serves as the main interrupt controller in the system. Non-legacy 12 - * hardware in the system uses this controller directly. Legacy devices 13 - * are connected to the PIIX4 which in turn has its 8259(s) connected to 14 - * a of the Cobalt APIC entry. 15 - * 16 - * 09/02/2000 - Updated for 2.4 by jbarnes@sgi.com 17 - * 18 - * 25/11/2002 - Updated for 2.5 by Andrey Panin <pazke@orbita1.ru> 19 - */ 20 - #include <linux/interrupt.h> 21 - #include <linux/module.h> 22 - #include <linux/init.h> 23 - #include <linux/smp.h> 24 - 25 - #include <asm/visws/cobalt.h> 26 - #include <asm/visws/piix4.h> 27 - #include <asm/io_apic.h> 28 - #include <asm/fixmap.h> 29 - #include <asm/reboot.h> 30 - #include <asm/setup.h> 31 - #include <asm/apic.h> 32 - #include <asm/e820.h> 33 - #include <asm/time.h> 34 - #include <asm/io.h> 35 - 36 - #include <linux/kernel_stat.h> 37 - 38 - #include <asm/i8259.h> 39 - #include <asm/irq_vectors.h> 40 - #include <asm/visws/lithium.h> 41 - 42 - #include <linux/sched.h> 43 - #include <linux/kernel.h> 44 - #include <linux/pci.h> 45 - #include <linux/pci_ids.h> 46 - 47 - extern int no_broadcast; 48 - 49 - char visws_board_type = -1; 50 - char visws_board_rev = -1; 51 - 52 - static void __init visws_time_init(void) 53 - { 54 - printk(KERN_INFO "Starting Cobalt Timer system clock\n"); 55 - 56 - /* Set the countdown value */ 57 - co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ); 58 - 59 - /* Start the timer */ 60 - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN); 61 - 62 - /* Enable (unmask) the timer interrupt */ 63 - co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); 64 - 65 - setup_default_timer_irq(); 66 - } 67 - 68 - /* Replaces the default init_ISA_irqs in the generic setup */ 69 - static void __init visws_pre_intr_init(void); 70 - 71 - /* Quirk for machine specific memory setup. */ 72 - 73 - #define MB (1024 * 1024) 74 - 75 - unsigned long sgivwfb_mem_phys; 76 - unsigned long sgivwfb_mem_size; 77 - EXPORT_SYMBOL(sgivwfb_mem_phys); 78 - EXPORT_SYMBOL(sgivwfb_mem_size); 79 - 80 - long long mem_size __initdata = 0; 81 - 82 - static char * __init visws_memory_setup(void) 83 - { 84 - long long gfx_mem_size = 8 * MB; 85 - 86 - mem_size = boot_params.alt_mem_k; 87 - 88 - if (!mem_size) { 89 - printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n"); 90 - mem_size = 128 * MB; 91 - } 92 - 93 - /* 94 - * this hardcodes the graphics memory to 8 MB 95 - * it really should be sized dynamically (or at least 96 - * set as a boot param) 97 - */ 98 - if (!sgivwfb_mem_size) { 99 - printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n"); 100 - sgivwfb_mem_size = 8 * MB; 101 - } 102 - 103 - /* 104 - * Trim to nearest MB 105 - */ 106 - sgivwfb_mem_size &= ~((1 << 20) - 1); 107 - sgivwfb_mem_phys = mem_size - gfx_mem_size; 108 - 109 - e820_add_region(0, LOWMEMSIZE(), E820_RAM); 110 - e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM); 111 - e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); 112 - 113 - return "PROM"; 114 - } 115 - 116 - static void visws_machine_emergency_restart(void) 117 - { 118 - /* 119 - * Visual Workstations restart after this 120 - * register is poked on the PIIX4 121 - */ 122 - outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT); 123 - } 124 - 125 - static void visws_machine_power_off(void) 126 - { 127 - unsigned short pm_status; 128 - /* extern unsigned int pci_bus0; */ 129 - 130 - while ((pm_status = inw(PMSTS_PORT)) & 0x100) 131 - outw(pm_status, PMSTS_PORT); 132 - 133 - outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT); 134 - 135 - mdelay(10); 136 - 137 - #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ 138 - (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) 139 - 140 - /* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */ 141 - outl(PIIX_SPECIAL_STOP, 0xCFC); 142 - } 143 - 144 - static void __init visws_get_smp_config(unsigned int early) 145 - { 146 - } 147 - 148 - /* 149 - * The Visual Workstation is Intel MP compliant in the hardware 150 - * sense, but it doesn't have a BIOS(-configuration table). 151 - * No problem for Linux. 152 - */ 153 - 154 - static void __init MP_processor_info(struct mpc_cpu *m) 155 - { 156 - int ver, logical_apicid; 157 - physid_mask_t apic_cpus; 158 - 159 - if (!(m->cpuflag & CPU_ENABLED)) 160 - return; 161 - 162 - logical_apicid = m->apicid; 163 - printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n", 164 - m->cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "", 165 - m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8, 166 - (m->cpufeature & CPU_MODEL_MASK) >> 4, m->apicver); 167 - 168 - if (m->cpuflag & CPU_BOOTPROCESSOR) 169 - boot_cpu_physical_apicid = m->apicid; 170 - 171 - ver = m->apicver; 172 - if ((ver >= 0x14 && m->apicid >= 0xff) || m->apicid >= 0xf) { 173 - printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", 174 - m->apicid, MAX_LOCAL_APIC); 175 - return; 176 - } 177 - 178 - apic->apicid_to_cpu_present(m->apicid, &apic_cpus); 179 - physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); 180 - /* 181 - * Validate version 182 - */ 183 - if (ver == 0x0) { 184 - printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! " 185 - "fixing up to 0x10. (tell your hw vendor)\n", 186 - m->apicid); 187 - ver = 0x10; 188 - } 189 - apic_version[m->apicid] = ver; 190 - } 191 - 192 - static void __init visws_find_smp_config(void) 193 - { 194 - struct mpc_cpu *mp = phys_to_virt(CO_CPU_TAB_PHYS); 195 - unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); 196 - 197 - if (ncpus > CO_CPU_MAX) { 198 - printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n", 199 - ncpus, mp); 200 - 201 - ncpus = CO_CPU_MAX; 202 - } 203 - 204 - if (ncpus > setup_max_cpus) 205 - ncpus = setup_max_cpus; 206 - 207 - #ifdef CONFIG_X86_LOCAL_APIC 208 - smp_found_config = 1; 209 - #endif 210 - while (ncpus--) 211 - MP_processor_info(mp++); 212 - 213 - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; 214 - } 215 - 216 - static void visws_trap_init(void); 217 - 218 - void __init visws_early_detect(void) 219 - { 220 - int raw; 221 - 222 - visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) 223 - >> PIIX_GPI_BD_SHIFT; 224 - 225 - if (visws_board_type < 0) 226 - return; 227 - 228 - /* 229 - * Override the default platform setup functions 230 - */ 231 - x86_init.resources.memory_setup = visws_memory_setup; 232 - x86_init.mpparse.get_smp_config = visws_get_smp_config; 233 - x86_init.mpparse.find_smp_config = visws_find_smp_config; 234 - x86_init.irqs.pre_vector_init = visws_pre_intr_init; 235 - x86_init.irqs.trap_init = visws_trap_init; 236 - x86_init.timers.timer_init = visws_time_init; 237 - x86_init.pci.init = pci_visws_init; 238 - x86_init.pci.init_irq = x86_init_noop; 239 - 240 - /* 241 - * Install reboot quirks: 242 - */ 243 - pm_power_off = visws_machine_power_off; 244 - machine_ops.emergency_restart = visws_machine_emergency_restart; 245 - 246 - /* 247 - * Do not use broadcast IPIs: 248 - */ 249 - no_broadcast = 0; 250 - 251 - #ifdef CONFIG_X86_IO_APIC 252 - /* 253 - * Turn off IO-APIC detection and initialization: 254 - */ 255 - skip_ioapic_setup = 1; 256 - #endif 257 - 258 - /* 259 - * Get Board rev. 260 - * First, we have to initialize the 307 part to allow us access 261 - * to the GPIO registers. Let's map them at 0x0fc0 which is right 262 - * after the PIIX4 PM section. 263 - */ 264 - outb_p(SIO_DEV_SEL, SIO_INDEX); 265 - outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ 266 - 267 - outb_p(SIO_DEV_MSB, SIO_INDEX); 268 - outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ 269 - 270 - outb_p(SIO_DEV_LSB, SIO_INDEX); 271 - outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ 272 - 273 - outb_p(SIO_DEV_ENB, SIO_INDEX); 274 - outb_p(1, SIO_DATA); /* Enable GPIO registers. */ 275 - 276 - /* 277 - * Now, we have to map the power management section to write 278 - * a bit which enables access to the GPIO registers. 279 - * What lunatic came up with this shit? 280 - */ 281 - outb_p(SIO_DEV_SEL, SIO_INDEX); 282 - outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ 283 - 284 - outb_p(SIO_DEV_MSB, SIO_INDEX); 285 - outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ 286 - 287 - outb_p(SIO_DEV_LSB, SIO_INDEX); 288 - outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ 289 - 290 - outb_p(SIO_DEV_ENB, SIO_INDEX); 291 - outb_p(1, SIO_DATA); /* Enable PM registers. */ 292 - 293 - /* 294 - * Now, write the PM register which enables the GPIO registers. 295 - */ 296 - outb_p(SIO_PM_FER2, SIO_PM_INDEX); 297 - outb_p(SIO_PM_GP_EN, SIO_PM_DATA); 298 - 299 - /* 300 - * Now, initialize the GPIO registers. 301 - * We want them all to be inputs which is the 302 - * power on default, so let's leave them alone. 303 - * So, let's just read the board rev! 304 - */ 305 - raw = inb_p(SIO_GP_DATA1); 306 - raw &= 0x7f; /* 7 bits of valid board revision ID. */ 307 - 308 - if (visws_board_type == VISWS_320) { 309 - if (raw < 0x6) { 310 - visws_board_rev = 4; 311 - } else if (raw < 0xc) { 312 - visws_board_rev = 5; 313 - } else { 314 - visws_board_rev = 6; 315 - } 316 - } else if (visws_board_type == VISWS_540) { 317 - visws_board_rev = 2; 318 - } else { 319 - visws_board_rev = raw; 320 - } 321 - 322 - printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n", 323 - (visws_board_type == VISWS_320 ? "320" : 324 - (visws_board_type == VISWS_540 ? "540" : 325 - "unknown")), visws_board_rev); 326 - } 327 - 328 - #define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4) 329 - #define BCD (LI_INTB | LI_INTC | LI_INTD) 330 - #define ALLDEVS (A01234 | BCD) 331 - 332 - static __init void lithium_init(void) 333 - { 334 - set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS); 335 - set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS); 336 - 337 - if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || 338 - (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { 339 - printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A'); 340 - /* panic("This machine is not SGI Visual Workstation 320/540"); */ 341 - } 342 - 343 - if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) || 344 - (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) { 345 - printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B'); 346 - /* panic("This machine is not SGI Visual Workstation 320/540"); */ 347 - } 348 - 349 - li_pcia_write16(LI_PCI_INTEN, ALLDEVS); 350 - li_pcib_write16(LI_PCI_INTEN, ALLDEVS); 351 - } 352 - 353 - static __init void cobalt_init(void) 354 - { 355 - /* 356 - * On normal SMP PC this is used only with SMP, but we have to 357 - * use it and set it up here to start the Cobalt clock 358 - */ 359 - set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE); 360 - setup_local_APIC(); 361 - printk(KERN_INFO "Local APIC Version %#x, ID %#x\n", 362 - (unsigned int)apic_read(APIC_LVR), 363 - (unsigned int)apic_read(APIC_ID)); 364 - 365 - set_fixmap(FIX_CO_CPU, CO_CPU_PHYS); 366 - set_fixmap(FIX_CO_APIC, CO_APIC_PHYS); 367 - printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n", 368 - co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID)); 369 - 370 - /* Enable Cobalt APIC being careful to NOT change the ID! */ 371 - co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE); 372 - 373 - printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n", 374 - co_apic_read(CO_APIC_ID)); 375 - } 376 - 377 - static void __init visws_trap_init(void) 378 - { 379 - lithium_init(); 380 - cobalt_init(); 381 - } 382 - 383 - /* 384 - * IRQ controller / APIC support: 385 - */ 386 - 387 - static DEFINE_SPINLOCK(cobalt_lock); 388 - 389 - /* 390 - * Set the given Cobalt APIC Redirection Table entry to point 391 - * to the given IDT vector/index. 392 - */ 393 - static inline void co_apic_set(int entry, int irq) 394 - { 395 - co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR)); 396 - co_apic_write(CO_APIC_HI(entry), 0); 397 - } 398 - 399 - /* 400 - * Cobalt (IO)-APIC functions to handle PCI devices. 401 - */ 402 - static inline int co_apic_ide0_hack(void) 403 - { 404 - extern char visws_board_type; 405 - extern char visws_board_rev; 406 - 407 - if (visws_board_type == VISWS_320 && visws_board_rev == 5) 408 - return 5; 409 - return CO_APIC_IDE0; 410 - } 411 - 412 - static int is_co_apic(unsigned int irq) 413 - { 414 - if (IS_CO_APIC(irq)) 415 - return CO_APIC(irq); 416 - 417 - switch (irq) { 418 - case 0: return CO_APIC_CPU; 419 - case CO_IRQ_IDE0: return co_apic_ide0_hack(); 420 - case CO_IRQ_IDE1: return CO_APIC_IDE1; 421 - default: return -1; 422 - } 423 - } 424 - 425 - 426 - /* 427 - * This is the SGI Cobalt (IO-)APIC: 428 - */ 429 - static void enable_cobalt_irq(struct irq_data *data) 430 - { 431 - co_apic_set(is_co_apic(data->irq), data->irq); 432 - } 433 - 434 - static void disable_cobalt_irq(struct irq_data *data) 435 - { 436 - int entry = is_co_apic(data->irq); 437 - 438 - co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK); 439 - co_apic_read(CO_APIC_LO(entry)); 440 - } 441 - 442 - static void ack_cobalt_irq(struct irq_data *data) 443 - { 444 - unsigned long flags; 445 - 446 - spin_lock_irqsave(&cobalt_lock, flags); 447 - disable_cobalt_irq(data); 448 - apic_write(APIC_EOI, APIC_EOI_ACK); 449 - spin_unlock_irqrestore(&cobalt_lock, flags); 450 - } 451 - 452 - static struct irq_chip cobalt_irq_type = { 453 - .name = "Cobalt-APIC", 454 - .irq_enable = enable_cobalt_irq, 455 - .irq_disable = disable_cobalt_irq, 456 - .irq_ack = ack_cobalt_irq, 457 - }; 458 - 459 - 460 - /* 461 - * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt 462 - * -- not the manner expected by the code in i8259.c. 463 - * 464 - * there is a 'master' physical interrupt source that gets sent to 465 - * the CPU. But in the chipset there are various 'virtual' interrupts 466 - * waiting to be handled. We represent this to Linux through a 'master' 467 - * interrupt controller type, and through a special virtual interrupt- 468 - * controller. Device drivers only see the virtual interrupt sources. 469 - */ 470 - static unsigned int startup_piix4_master_irq(struct irq_data *data) 471 - { 472 - legacy_pic->init(0); 473 - enable_cobalt_irq(data); 474 - return 0; 475 - } 476 - 477 - static struct irq_chip piix4_master_irq_type = { 478 - .name = "PIIX4-master", 479 - .irq_startup = startup_piix4_master_irq, 480 - .irq_ack = ack_cobalt_irq, 481 - }; 482 - 483 - static void pii4_mask(struct irq_data *data) { } 484 - 485 - static struct irq_chip piix4_virtual_irq_type = { 486 - .name = "PIIX4-virtual", 487 - .irq_mask = pii4_mask, 488 - }; 489 - 490 - /* 491 - * PIIX4-8259 master/virtual functions to handle interrupt requests 492 - * from legacy devices: floppy, parallel, serial, rtc. 493 - * 494 - * None of these get Cobalt APIC entries, neither do they have IDT 495 - * entries. These interrupts are purely virtual and distributed from 496 - * the 'master' interrupt source: CO_IRQ_8259. 497 - * 498 - * When the 8259 interrupts its handler figures out which of these 499 - * devices is interrupting and dispatches to its handler. 500 - * 501 - * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/ 502 - * enable_irq gets the right irq. This 'master' irq is never directly 503 - * manipulated by any driver. 504 - */ 505 - static irqreturn_t piix4_master_intr(int irq, void *dev_id) 506 - { 507 - unsigned long flags; 508 - int realirq; 509 - 510 - raw_spin_lock_irqsave(&i8259A_lock, flags); 511 - 512 - /* Find out what's interrupting in the PIIX4 master 8259 */ 513 - outb(0x0c, 0x20); /* OCW3 Poll command */ 514 - realirq = inb(0x20); 515 - 516 - /* 517 - * Bit 7 == 0 means invalid/spurious 518 - */ 519 - if (unlikely(!(realirq & 0x80))) 520 - goto out_unlock; 521 - 522 - realirq &= 7; 523 - 524 - if (unlikely(realirq == 2)) { 525 - outb(0x0c, 0xa0); 526 - realirq = inb(0xa0); 527 - 528 - if (unlikely(!(realirq & 0x80))) 529 - goto out_unlock; 530 - 531 - realirq = (realirq & 7) + 8; 532 - } 533 - 534 - /* mask and ack interrupt */ 535 - cached_irq_mask |= 1 << realirq; 536 - if (unlikely(realirq > 7)) { 537 - inb(0xa1); 538 - outb(cached_slave_mask, 0xa1); 539 - outb(0x60 + (realirq & 7), 0xa0); 540 - outb(0x60 + 2, 0x20); 541 - } else { 542 - inb(0x21); 543 - outb(cached_master_mask, 0x21); 544 - outb(0x60 + realirq, 0x20); 545 - } 546 - 547 - raw_spin_unlock_irqrestore(&i8259A_lock, flags); 548 - 549 - /* 550 - * handle this 'virtual interrupt' as a Cobalt one now. 551 - */ 552 - generic_handle_irq(realirq); 553 - 554 - return IRQ_HANDLED; 555 - 556 - out_unlock: 557 - raw_spin_unlock_irqrestore(&i8259A_lock, flags); 558 - return IRQ_NONE; 559 - } 560 - 561 - static struct irqaction master_action = { 562 - .handler = piix4_master_intr, 563 - .name = "PIIX4-8259", 564 - .flags = IRQF_NO_THREAD, 565 - }; 566 - 567 - static struct irqaction cascade_action = { 568 - .handler = no_action, 569 - .name = "cascade", 570 - .flags = IRQF_NO_THREAD, 571 - }; 572 - 573 - static inline void set_piix4_virtual_irq_type(void) 574 - { 575 - piix4_virtual_irq_type.irq_enable = i8259A_chip.irq_unmask; 576 - piix4_virtual_irq_type.irq_disable = i8259A_chip.irq_mask; 577 - piix4_virtual_irq_type.irq_unmask = i8259A_chip.irq_unmask; 578 - } 579 - 580 - static void __init visws_pre_intr_init(void) 581 - { 582 - int i; 583 - 584 - set_piix4_virtual_irq_type(); 585 - 586 - for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) { 587 - struct irq_chip *chip = NULL; 588 - 589 - if (i == 0) 590 - chip = &cobalt_irq_type; 591 - else if (i == CO_IRQ_IDE0) 592 - chip = &cobalt_irq_type; 593 - else if (i == CO_IRQ_IDE1) 594 - chip = &cobalt_irq_type; 595 - else if (i == CO_IRQ_8259) 596 - chip = &piix4_master_irq_type; 597 - else if (i < CO_IRQ_APIC0) 598 - chip = &piix4_virtual_irq_type; 599 - else if (IS_CO_APIC(i)) 600 - chip = &cobalt_irq_type; 601 - 602 - if (chip) 603 - irq_set_chip(i, chip); 604 - } 605 - 606 - setup_irq(CO_IRQ_8259, &master_action); 607 - setup_irq(2, &cascade_action); 608 - }
+1 -1
arch/x86/xen/Kconfig
··· 7 7 depends on PARAVIRT 8 8 select PARAVIRT_CLOCK 9 9 select XEN_HAVE_PVMMU 10 - depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) 10 + depends on X86_64 || (X86_32 && X86_PAE) 11 11 depends on X86_TSC 12 12 help 13 13 This is the Linux Xen port. Enabling this will allow the
-1
drivers/pci/Makefile
··· 42 42 obj-$(CONFIG_PPC) += setup-bus.o 43 43 obj-$(CONFIG_FRV) += setup-bus.o 44 44 obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o 45 - obj-$(CONFIG_X86_VISWS) += setup-irq.o 46 45 obj-$(CONFIG_MN10300) += setup-bus.o 47 46 obj-$(CONFIG_MICROBLAZE) += setup-bus.o 48 47 obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o
-7
drivers/scsi/qla1280.c
··· 379 379 #define DEBUG_PRINT_NVRAM 0 380 380 #define DEBUG_QLA1280 0 381 381 382 - /* 383 - * The SGI VISWS is broken and doesn't support MMIO ;-( 384 - */ 385 - #ifdef CONFIG_X86_VISWS 386 - #define MEMORY_MAPPED_IO 0 387 - #else 388 382 #define MEMORY_MAPPED_IO 1 389 - #endif 390 383 391 384 #include "qla1280.h" 392 385
+1 -10
drivers/video/Kconfig
··· 802 802 As this card technology is at least 25 years old, 803 803 most people will answer N here. 804 804 805 - config FB_SGIVW 806 - tristate "SGI Visual Workstation framebuffer support" 807 - depends on FB && X86_VISWS 808 - select FB_CFB_FILLRECT 809 - select FB_CFB_COPYAREA 810 - select FB_CFB_IMAGEBLIT 811 - help 812 - SGI Visual Workstation support for framebuffer graphics. 813 - 814 805 config FB_GBE 815 806 bool "SGI Graphics Backend frame buffer support" 816 - depends on (FB = y) && (SGI_IP32 || X86_VISWS) 807 + depends on (FB = y) && SGI_IP32 817 808 select FB_CFB_FILLRECT 818 809 select FB_CFB_COPYAREA 819 810 select FB_CFB_IMAGEBLIT
-1
drivers/video/Makefile
··· 75 75 obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o 76 76 obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o 77 77 obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o 78 - obj-$(CONFIG_FB_SGIVW) += sgivwfb.o 79 78 obj-$(CONFIG_FB_ACORN) += acornfb.o 80 79 obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ 81 80 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
-4
drivers/video/gbefb.c
··· 45 45 #define GBE_BASE 0x16000000 /* SGI O2 */ 46 46 #endif 47 47 48 - #ifdef CONFIG_X86_VISWS 49 - #define GBE_BASE 0xd0000000 /* SGI Visual Workstation */ 50 - #endif 51 - 52 48 /* macro for fastest write-though access to the framebuffer */ 53 49 #ifdef CONFIG_MIPS 54 50 #ifdef CONFIG_CPU_R10000
+1 -1
drivers/video/logo/Kconfig
··· 54 54 55 55 config LOGO_SGI_CLUT224 56 56 bool "224-color SGI Linux logo" 57 - depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS 57 + depends on SGI_IP22 || SGI_IP27 || SGI_IP32 58 58 default y 59 59 60 60 config LOGO_SUN_CLUT224
+1 -1
drivers/video/logo/logo.c
··· 81 81 logo = &logo_parisc_clut224; 82 82 #endif 83 83 #ifdef CONFIG_LOGO_SGI_CLUT224 84 - /* SGI Linux logo on MIPS/MIPS64 and VISWS */ 84 + /* SGI Linux logo on MIPS/MIPS64 */ 85 85 logo = &logo_sgi_clut224; 86 86 #endif 87 87 #ifdef CONFIG_LOGO_SUN_CLUT224
-889
drivers/video/sgivwfb.c
··· 1 - /* 2 - * linux/drivers/video/sgivwfb.c -- SGI DBE frame buffer device 3 - * 4 - * Copyright (C) 1999 Silicon Graphics, Inc. 5 - * Jeffrey Newquist, newquist@engr.sgi.som 6 - * 7 - * This file is subject to the terms and conditions of the GNU General Public 8 - * License. See the file COPYING in the main directory of this archive for 9 - * more details. 10 - */ 11 - 12 - #include <linux/module.h> 13 - #include <linux/kernel.h> 14 - #include <linux/mm.h> 15 - #include <linux/errno.h> 16 - #include <linux/delay.h> 17 - #include <linux/fb.h> 18 - #include <linux/init.h> 19 - #include <linux/ioport.h> 20 - #include <linux/platform_device.h> 21 - 22 - #include <asm/io.h> 23 - #include <asm/mtrr.h> 24 - #include <asm/visws/sgivw.h> 25 - 26 - #define INCLUDE_TIMING_TABLE_DATA 27 - #define DBE_REG_BASE par->regs 28 - #include <video/sgivw.h> 29 - 30 - struct sgivw_par { 31 - struct asregs *regs; 32 - u32 cmap_fifo; 33 - u_long timing_num; 34 - }; 35 - 36 - #define FLATPANEL_SGI_1600SW 5 37 - 38 - /* 39 - * RAM we reserve for the frame buffer. This defines the maximum screen 40 - * size 41 - * 42 - * The default can be overridden if the driver is compiled as a module 43 - */ 44 - 45 - static int ypan = 0; 46 - static int ywrap = 0; 47 - 48 - static int flatpanel_id = -1; 49 - 50 - static struct fb_fix_screeninfo sgivwfb_fix = { 51 - .id = "SGI Vis WS FB", 52 - .type = FB_TYPE_PACKED_PIXELS, 53 - .visual = FB_VISUAL_PSEUDOCOLOR, 54 - .mmio_start = DBE_REG_PHYS, 55 - .mmio_len = DBE_REG_SIZE, 56 - .accel = FB_ACCEL_NONE, 57 - .line_length = 640, 58 - }; 59 - 60 - static struct fb_var_screeninfo sgivwfb_var = { 61 - /* 640x480, 8 bpp */ 62 - .xres = 640, 63 - .yres = 480, 64 - .xres_virtual = 640, 65 - .yres_virtual = 480, 66 - .bits_per_pixel = 8, 67 - .red = { 0, 8, 0 }, 68 - .green = { 0, 8, 0 }, 69 - .blue = { 0, 8, 0 }, 70 - .height = -1, 71 - .width = -1, 72 - .pixclock = 20000, 73 - .left_margin = 64, 74 - .right_margin = 64, 75 - .upper_margin = 32, 76 - .lower_margin = 32, 77 - .hsync_len = 64, 78 - .vsync_len = 2, 79 - .vmode = FB_VMODE_NONINTERLACED 80 - }; 81 - 82 - static struct fb_var_screeninfo sgivwfb_var1600sw = { 83 - /* 1600x1024, 8 bpp */ 84 - .xres = 1600, 85 - .yres = 1024, 86 - .xres_virtual = 1600, 87 - .yres_virtual = 1024, 88 - .bits_per_pixel = 8, 89 - .red = { 0, 8, 0 }, 90 - .green = { 0, 8, 0 }, 91 - .blue = { 0, 8, 0 }, 92 - .height = -1, 93 - .width = -1, 94 - .pixclock = 9353, 95 - .left_margin = 20, 96 - .right_margin = 30, 97 - .upper_margin = 37, 98 - .lower_margin = 3, 99 - .hsync_len = 20, 100 - .vsync_len = 3, 101 - .vmode = FB_VMODE_NONINTERLACED 102 - }; 103 - 104 - /* 105 - * Interface used by the world 106 - */ 107 - int sgivwfb_init(void); 108 - 109 - static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); 110 - static int sgivwfb_set_par(struct fb_info *info); 111 - static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, 112 - u_int blue, u_int transp, 113 - struct fb_info *info); 114 - static int sgivwfb_mmap(struct fb_info *info, 115 - struct vm_area_struct *vma); 116 - 117 - static struct fb_ops sgivwfb_ops = { 118 - .owner = THIS_MODULE, 119 - .fb_check_var = sgivwfb_check_var, 120 - .fb_set_par = sgivwfb_set_par, 121 - .fb_setcolreg = sgivwfb_setcolreg, 122 - .fb_fillrect = cfb_fillrect, 123 - .fb_copyarea = cfb_copyarea, 124 - .fb_imageblit = cfb_imageblit, 125 - .fb_mmap = sgivwfb_mmap, 126 - }; 127 - 128 - /* 129 - * Internal routines 130 - */ 131 - static unsigned long bytes_per_pixel(int bpp) 132 - { 133 - switch (bpp) { 134 - case 8: 135 - return 1; 136 - case 16: 137 - return 2; 138 - case 32: 139 - return 4; 140 - default: 141 - printk(KERN_INFO "sgivwfb: unsupported bpp %d\n", bpp); 142 - return 0; 143 - } 144 - } 145 - 146 - static unsigned long get_line_length(int xres_virtual, int bpp) 147 - { 148 - return (xres_virtual * bytes_per_pixel(bpp)); 149 - } 150 - 151 - /* 152 - * Function: dbe_TurnOffDma 153 - * Parameters: (None) 154 - * Description: This should turn off the monitor and dbe. This is used 155 - * when switching between the serial console and the graphics 156 - * console. 157 - */ 158 - 159 - static void dbe_TurnOffDma(struct sgivw_par *par) 160 - { 161 - unsigned int readVal; 162 - int i; 163 - 164 - // Check to see if things are already turned off: 165 - // 1) Check to see if dbe is not using the internal dotclock. 166 - // 2) Check to see if the xy counter in dbe is already off. 167 - 168 - DBE_GETREG(ctrlstat, readVal); 169 - if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2) 170 - return; 171 - 172 - DBE_GETREG(vt_xy, readVal); 173 - if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) 174 - return; 175 - 176 - // Otherwise, turn off dbe 177 - 178 - DBE_GETREG(ovr_control, readVal); 179 - SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0); 180 - DBE_SETREG(ovr_control, readVal); 181 - udelay(1000); 182 - DBE_GETREG(frm_control, readVal); 183 - SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0); 184 - DBE_SETREG(frm_control, readVal); 185 - udelay(1000); 186 - DBE_GETREG(did_control, readVal); 187 - SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0); 188 - DBE_SETREG(did_control, readVal); 189 - udelay(1000); 190 - 191 - // XXX HACK: 192 - // 193 - // This was necessary for GBE--we had to wait through two 194 - // vertical retrace periods before the pixel DMA was 195 - // turned off for sure. I've left this in for now, in 196 - // case dbe needs it. 197 - 198 - for (i = 0; i < 10000; i++) { 199 - DBE_GETREG(frm_inhwctrl, readVal); 200 - if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) == 201 - 0) 202 - udelay(10); 203 - else { 204 - DBE_GETREG(ovr_inhwctrl, readVal); 205 - if (GET_DBE_FIELD 206 - (OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0) 207 - udelay(10); 208 - else { 209 - DBE_GETREG(did_inhwctrl, readVal); 210 - if (GET_DBE_FIELD 211 - (DID_INHWCTRL, DID_DMA_ENABLE, 212 - readVal) == 0) 213 - udelay(10); 214 - else 215 - break; 216 - } 217 - } 218 - } 219 - } 220 - 221 - /* 222 - * Set the User Defined Part of the Display. Again if par use it to get 223 - * real video mode. 224 - */ 225 - static int sgivwfb_check_var(struct fb_var_screeninfo *var, 226 - struct fb_info *info) 227 - { 228 - struct sgivw_par *par = (struct sgivw_par *)info->par; 229 - struct dbe_timing_info *timing; 230 - u_long line_length; 231 - u_long min_mode; 232 - int req_dot; 233 - int test_mode; 234 - 235 - /* 236 - * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! 237 - * as FB_VMODE_SMOOTH_XPAN is only used internally 238 - */ 239 - 240 - if (var->vmode & FB_VMODE_CONUPDATE) { 241 - var->vmode |= FB_VMODE_YWRAP; 242 - var->xoffset = info->var.xoffset; 243 - var->yoffset = info->var.yoffset; 244 - } 245 - 246 - /* XXX FIXME - forcing var's */ 247 - var->xoffset = 0; 248 - var->yoffset = 0; 249 - 250 - /* Limit bpp to 8, 16, and 32 */ 251 - if (var->bits_per_pixel <= 8) 252 - var->bits_per_pixel = 8; 253 - else if (var->bits_per_pixel <= 16) 254 - var->bits_per_pixel = 16; 255 - else if (var->bits_per_pixel <= 32) 256 - var->bits_per_pixel = 32; 257 - else 258 - return -EINVAL; 259 - 260 - var->grayscale = 0; /* No grayscale for now */ 261 - 262 - /* determine valid resolution and timing */ 263 - for (min_mode = 0; min_mode < ARRAY_SIZE(dbeVTimings); min_mode++) { 264 - if (dbeVTimings[min_mode].width >= var->xres && 265 - dbeVTimings[min_mode].height >= var->yres) 266 - break; 267 - } 268 - 269 - if (min_mode == ARRAY_SIZE(dbeVTimings)) 270 - return -EINVAL; /* Resolution to high */ 271 - 272 - /* XXX FIXME - should try to pick best refresh rate */ 273 - /* for now, pick closest dot-clock within 3MHz */ 274 - req_dot = PICOS2KHZ(var->pixclock); 275 - printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n", 276 - var->pixclock, req_dot); 277 - test_mode = min_mode; 278 - while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) { 279 - if (dbeVTimings[test_mode].cfreq + 3000 > req_dot) 280 - break; 281 - test_mode++; 282 - } 283 - if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width) 284 - test_mode--; 285 - min_mode = test_mode; 286 - timing = &dbeVTimings[min_mode]; 287 - printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq); 288 - 289 - /* Adjust virtual resolution, if necessary */ 290 - if (var->xres > var->xres_virtual || (!ywrap && !ypan)) 291 - var->xres_virtual = var->xres; 292 - if (var->yres > var->yres_virtual || (!ywrap && !ypan)) 293 - var->yres_virtual = var->yres; 294 - 295 - /* 296 - * Memory limit 297 - */ 298 - line_length = get_line_length(var->xres_virtual, var->bits_per_pixel); 299 - if (line_length * var->yres_virtual > sgivwfb_mem_size) 300 - return -ENOMEM; /* Virtual resolution to high */ 301 - 302 - info->fix.line_length = line_length; 303 - 304 - switch (var->bits_per_pixel) { 305 - case 8: 306 - var->red.offset = 0; 307 - var->red.length = 8; 308 - var->green.offset = 0; 309 - var->green.length = 8; 310 - var->blue.offset = 0; 311 - var->blue.length = 8; 312 - var->transp.offset = 0; 313 - var->transp.length = 0; 314 - break; 315 - case 16: /* RGBA 5551 */ 316 - var->red.offset = 11; 317 - var->red.length = 5; 318 - var->green.offset = 6; 319 - var->green.length = 5; 320 - var->blue.offset = 1; 321 - var->blue.length = 5; 322 - var->transp.offset = 0; 323 - var->transp.length = 0; 324 - break; 325 - case 32: /* RGB 8888 */ 326 - var->red.offset = 0; 327 - var->red.length = 8; 328 - var->green.offset = 8; 329 - var->green.length = 8; 330 - var->blue.offset = 16; 331 - var->blue.length = 8; 332 - var->transp.offset = 24; 333 - var->transp.length = 8; 334 - break; 335 - } 336 - var->red.msb_right = 0; 337 - var->green.msb_right = 0; 338 - var->blue.msb_right = 0; 339 - var->transp.msb_right = 0; 340 - 341 - /* set video timing information */ 342 - var->pixclock = KHZ2PICOS(timing->cfreq); 343 - var->left_margin = timing->htotal - timing->hsync_end; 344 - var->right_margin = timing->hsync_start - timing->width; 345 - var->upper_margin = timing->vtotal - timing->vsync_end; 346 - var->lower_margin = timing->vsync_start - timing->height; 347 - var->hsync_len = timing->hsync_end - timing->hsync_start; 348 - var->vsync_len = timing->vsync_end - timing->vsync_start; 349 - 350 - /* Ouch. This breaks the rules but timing_num is only important if you 351 - * change a video mode */ 352 - par->timing_num = min_mode; 353 - 354 - printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n", 355 - var->xres, var->yres, var->bits_per_pixel); 356 - printk(KERN_INFO " vxres=%d vyres=%d\n", var->xres_virtual, 357 - var->yres_virtual); 358 - return 0; 359 - } 360 - 361 - /* 362 - * Setup flatpanel related registers. 363 - */ 364 - static void sgivwfb_setup_flatpanel(struct sgivw_par *par, struct dbe_timing_info *currentTiming) 365 - { 366 - int fp_wid, fp_hgt, fp_vbs, fp_vbe; 367 - u32 outputVal = 0; 368 - 369 - SET_DBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal, 370 - (currentTiming->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1); 371 - SET_DBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal, 372 - (currentTiming->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1); 373 - DBE_SETREG(vt_flags, outputVal); 374 - 375 - /* Turn on the flat panel */ 376 - switch (flatpanel_id) { 377 - case FLATPANEL_SGI_1600SW: 378 - fp_wid = 1600; 379 - fp_hgt = 1024; 380 - fp_vbs = 0; 381 - fp_vbe = 1600; 382 - currentTiming->pll_m = 4; 383 - currentTiming->pll_n = 1; 384 - currentTiming->pll_p = 0; 385 - break; 386 - default: 387 - fp_wid = fp_hgt = fp_vbs = fp_vbe = 0xfff; 388 - } 389 - 390 - outputVal = 0; 391 - SET_DBE_FIELD(FP_DE, FP_DE_ON, outputVal, fp_vbs); 392 - SET_DBE_FIELD(FP_DE, FP_DE_OFF, outputVal, fp_vbe); 393 - DBE_SETREG(fp_de, outputVal); 394 - outputVal = 0; 395 - SET_DBE_FIELD(FP_HDRV, FP_HDRV_OFF, outputVal, fp_wid); 396 - DBE_SETREG(fp_hdrv, outputVal); 397 - outputVal = 0; 398 - SET_DBE_FIELD(FP_VDRV, FP_VDRV_ON, outputVal, 1); 399 - SET_DBE_FIELD(FP_VDRV, FP_VDRV_OFF, outputVal, fp_hgt + 1); 400 - DBE_SETREG(fp_vdrv, outputVal); 401 - } 402 - 403 - /* 404 - * Set the hardware according to 'par'. 405 - */ 406 - static int sgivwfb_set_par(struct fb_info *info) 407 - { 408 - struct sgivw_par *par = info->par; 409 - int i, j, htmp, temp; 410 - u32 readVal, outputVal; 411 - int wholeTilesX, maxPixelsPerTileX; 412 - int frmWrite1, frmWrite2, frmWrite3b; 413 - struct dbe_timing_info *currentTiming; /* Current Video Timing */ 414 - int xpmax, ypmax; // Monitor resolution 415 - int bytesPerPixel; // Bytes per pixel 416 - 417 - currentTiming = &dbeVTimings[par->timing_num]; 418 - bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel); 419 - xpmax = currentTiming->width; 420 - ypmax = currentTiming->height; 421 - 422 - /* dbe_InitGraphicsBase(); */ 423 - /* Turn on dotclock PLL */ 424 - DBE_SETREG(ctrlstat, 0x20000000); 425 - 426 - dbe_TurnOffDma(par); 427 - 428 - /* dbe_CalculateScreenParams(); */ 429 - maxPixelsPerTileX = 512 / bytesPerPixel; 430 - wholeTilesX = xpmax / maxPixelsPerTileX; 431 - if (wholeTilesX * maxPixelsPerTileX < xpmax) 432 - wholeTilesX++; 433 - 434 - printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n", 435 - maxPixelsPerTileX, wholeTilesX); 436 - 437 - /* dbe_InitGammaMap(); */ 438 - udelay(10); 439 - 440 - for (i = 0; i < 256; i++) { 441 - DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8)); 442 - } 443 - 444 - /* dbe_TurnOn(); */ 445 - DBE_GETREG(vt_xy, readVal); 446 - if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) { 447 - DBE_SETREG(vt_xy, 0x00000000); 448 - udelay(1); 449 - } else 450 - dbe_TurnOffDma(par); 451 - 452 - /* dbe_Initdbe(); */ 453 - for (i = 0; i < 256; i++) { 454 - for (j = 0; j < 100; j++) { 455 - DBE_GETREG(cm_fifo, readVal); 456 - if (readVal != 0x00000000) 457 - break; 458 - else 459 - udelay(10); 460 - } 461 - 462 - // DBE_ISETREG(cmap, i, 0x00000000); 463 - DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24)); 464 - } 465 - 466 - /* dbe_InitFramebuffer(); */ 467 - frmWrite1 = 0; 468 - SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1, 469 - wholeTilesX); 470 - SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0); 471 - 472 - switch (bytesPerPixel) { 473 - case 1: 474 - SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, 475 - DBE_FRM_DEPTH_8); 476 - break; 477 - case 2: 478 - SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, 479 - DBE_FRM_DEPTH_16); 480 - break; 481 - case 4: 482 - SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, 483 - DBE_FRM_DEPTH_32); 484 - break; 485 - } 486 - 487 - frmWrite2 = 0; 488 - SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax); 489 - 490 - // Tell dbe about the framebuffer location and type 491 - // XXX What format is the FRM_TILE_PTR?? 64K aligned address? 492 - frmWrite3b = 0; 493 - SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b, 494 - sgivwfb_mem_phys >> 9); 495 - SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1); 496 - SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1); 497 - 498 - /* Initialize DIDs */ 499 - 500 - outputVal = 0; 501 - switch (bytesPerPixel) { 502 - case 1: 503 - SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8); 504 - break; 505 - case 2: 506 - SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5); 507 - break; 508 - case 4: 509 - SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8); 510 - break; 511 - } 512 - SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH); 513 - 514 - for (i = 0; i < 32; i++) { 515 - DBE_ISETREG(mode_regs, i, outputVal); 516 - } 517 - 518 - /* dbe_InitTiming(); */ 519 - DBE_SETREG(vt_intr01, 0xffffffff); 520 - DBE_SETREG(vt_intr23, 0xffffffff); 521 - 522 - DBE_GETREG(dotclock, readVal); 523 - DBE_SETREG(dotclock, readVal & 0xffff); 524 - 525 - DBE_SETREG(vt_xymax, 0x00000000); 526 - outputVal = 0; 527 - SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal, 528 - currentTiming->vsync_start); 529 - SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal, 530 - currentTiming->vsync_end); 531 - DBE_SETREG(vt_vsync, outputVal); 532 - outputVal = 0; 533 - SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal, 534 - currentTiming->hsync_start); 535 - SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal, 536 - currentTiming->hsync_end); 537 - DBE_SETREG(vt_hsync, outputVal); 538 - outputVal = 0; 539 - SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal, 540 - currentTiming->vblank_start); 541 - SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal, 542 - currentTiming->vblank_end); 543 - DBE_SETREG(vt_vblank, outputVal); 544 - outputVal = 0; 545 - SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal, 546 - currentTiming->hblank_start); 547 - SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal, 548 - currentTiming->hblank_end - 3); 549 - DBE_SETREG(vt_hblank, outputVal); 550 - outputVal = 0; 551 - SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal, 552 - currentTiming->vblank_start); 553 - SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal, 554 - currentTiming->vblank_end); 555 - DBE_SETREG(vt_vcmap, outputVal); 556 - outputVal = 0; 557 - SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal, 558 - currentTiming->hblank_start); 559 - SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal, 560 - currentTiming->hblank_end - 3); 561 - DBE_SETREG(vt_hcmap, outputVal); 562 - 563 - if (flatpanel_id != -1) 564 - sgivwfb_setup_flatpanel(par, currentTiming); 565 - 566 - outputVal = 0; 567 - temp = currentTiming->vblank_start - currentTiming->vblank_end - 1; 568 - if (temp > 0) 569 - temp = -temp; 570 - 571 - SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp); 572 - if (currentTiming->hblank_end >= 20) 573 - SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal, 574 - currentTiming->hblank_end - 20); 575 - else 576 - SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal, 577 - currentTiming->htotal - (20 - 578 - currentTiming-> 579 - hblank_end)); 580 - DBE_SETREG(did_start_xy, outputVal); 581 - 582 - outputVal = 0; 583 - SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal, 584 - (u32) (temp + 1)); 585 - if (currentTiming->hblank_end >= DBE_CRS_MAGIC) 586 - SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal, 587 - currentTiming->hblank_end - DBE_CRS_MAGIC); 588 - else 589 - SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal, 590 - currentTiming->htotal - (DBE_CRS_MAGIC - 591 - currentTiming-> 592 - hblank_end)); 593 - DBE_SETREG(crs_start_xy, outputVal); 594 - 595 - outputVal = 0; 596 - SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp); 597 - SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal, 598 - currentTiming->hblank_end - 4); 599 - DBE_SETREG(vc_start_xy, outputVal); 600 - 601 - DBE_SETREG(frm_size_tile, frmWrite1); 602 - DBE_SETREG(frm_size_pixel, frmWrite2); 603 - 604 - outputVal = 0; 605 - SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1); 606 - SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1); 607 - SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p); 608 - SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1); 609 - DBE_SETREG(dotclock, outputVal); 610 - 611 - udelay(11 * 1000); 612 - 613 - DBE_SETREG(vt_vpixen, 0xffffff); 614 - DBE_SETREG(vt_hpixen, 0xffffff); 615 - 616 - outputVal = 0; 617 - SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal); 618 - SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal); 619 - DBE_SETREG(vt_xymax, outputVal); 620 - 621 - outputVal = frmWrite1; 622 - SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1); 623 - DBE_SETREG(frm_size_tile, outputVal); 624 - DBE_SETREG(frm_size_tile, frmWrite1); 625 - 626 - outputVal = 0; 627 - SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1); 628 - DBE_SETREG(ovr_width_tile, outputVal); 629 - DBE_SETREG(ovr_width_tile, 0); 630 - 631 - DBE_SETREG(frm_control, frmWrite3b); 632 - DBE_SETREG(did_control, 0); 633 - 634 - // Wait for dbe to take frame settings 635 - for (i = 0; i < 100000; i++) { 636 - DBE_GETREG(frm_inhwctrl, readVal); 637 - if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) != 638 - 0) 639 - break; 640 - else 641 - udelay(1); 642 - } 643 - 644 - if (i == 100000) 645 - printk(KERN_INFO 646 - "sgivwfb: timeout waiting for frame DMA enable.\n"); 647 - 648 - outputVal = 0; 649 - htmp = currentTiming->hblank_end - 19; 650 - if (htmp < 0) 651 - htmp += currentTiming->htotal; /* allow blank to wrap around */ 652 - SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp); 653 - SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal, 654 - ((htmp + currentTiming->width - 655 - 2) % currentTiming->htotal)); 656 - DBE_SETREG(vt_hpixen, outputVal); 657 - 658 - outputVal = 0; 659 - SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal, 660 - currentTiming->vblank_start); 661 - SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal, 662 - currentTiming->vblank_end); 663 - DBE_SETREG(vt_vpixen, outputVal); 664 - 665 - // Turn off mouse cursor 666 - par->regs->crs_ctl = 0; 667 - 668 - // XXX What's this section for?? 669 - DBE_GETREG(ctrlstat, readVal); 670 - readVal &= 0x02000000; 671 - 672 - if (readVal != 0) { 673 - DBE_SETREG(ctrlstat, 0x30000000); 674 - } 675 - return 0; 676 - } 677 - 678 - /* 679 - * Set a single color register. The values supplied are already 680 - * rounded down to the hardware's capabilities (according to the 681 - * entries in the var structure). Return != 0 for invalid regno. 682 - */ 683 - 684 - static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, 685 - u_int blue, u_int transp, 686 - struct fb_info *info) 687 - { 688 - struct sgivw_par *par = (struct sgivw_par *) info->par; 689 - 690 - if (regno > 255) 691 - return 1; 692 - red >>= 8; 693 - green >>= 8; 694 - blue >>= 8; 695 - 696 - /* wait for the color map FIFO to have a free entry */ 697 - while (par->cmap_fifo == 0) 698 - par->cmap_fifo = par->regs->cm_fifo; 699 - 700 - par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8); 701 - par->cmap_fifo--; /* assume FIFO is filling up */ 702 - return 0; 703 - } 704 - 705 - static int sgivwfb_mmap(struct fb_info *info, 706 - struct vm_area_struct *vma) 707 - { 708 - int r; 709 - 710 - pgprot_val(vma->vm_page_prot) = 711 - pgprot_val(vma->vm_page_prot) | _PAGE_PCD; 712 - 713 - r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size); 714 - 715 - printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", 716 - sgivwfb_mem_phys + (vma->vm_pgoff << PAGE_SHIFT), vma->vm_start); 717 - 718 - return r; 719 - } 720 - 721 - int __init sgivwfb_setup(char *options) 722 - { 723 - char *this_opt; 724 - 725 - if (!options || !*options) 726 - return 0; 727 - 728 - while ((this_opt = strsep(&options, ",")) != NULL) { 729 - if (!strncmp(this_opt, "monitor:", 8)) { 730 - if (!strncmp(this_opt + 8, "crt", 3)) 731 - flatpanel_id = -1; 732 - else if (!strncmp(this_opt + 8, "1600sw", 6)) 733 - flatpanel_id = FLATPANEL_SGI_1600SW; 734 - } 735 - } 736 - return 0; 737 - } 738 - 739 - /* 740 - * Initialisation 741 - */ 742 - static int sgivwfb_probe(struct platform_device *dev) 743 - { 744 - struct sgivw_par *par; 745 - struct fb_info *info; 746 - char *monitor; 747 - 748 - info = framebuffer_alloc(sizeof(struct sgivw_par) + sizeof(u32) * 16, &dev->dev); 749 - if (!info) 750 - return -ENOMEM; 751 - par = info->par; 752 - 753 - if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) { 754 - printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n"); 755 - framebuffer_release(info); 756 - return -EBUSY; 757 - } 758 - 759 - par->regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE); 760 - if (!par->regs) { 761 - printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n"); 762 - goto fail_ioremap_regs; 763 - } 764 - 765 - mtrr_add(sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1); 766 - 767 - sgivwfb_fix.smem_start = sgivwfb_mem_phys; 768 - sgivwfb_fix.smem_len = sgivwfb_mem_size; 769 - sgivwfb_fix.ywrapstep = ywrap; 770 - sgivwfb_fix.ypanstep = ypan; 771 - 772 - info->fix = sgivwfb_fix; 773 - 774 - switch (flatpanel_id) { 775 - case FLATPANEL_SGI_1600SW: 776 - info->var = sgivwfb_var1600sw; 777 - monitor = "SGI 1600SW flatpanel"; 778 - break; 779 - default: 780 - info->var = sgivwfb_var; 781 - monitor = "CRT"; 782 - } 783 - 784 - printk(KERN_INFO "sgivwfb: %s monitor selected\n", monitor); 785 - 786 - info->fbops = &sgivwfb_ops; 787 - info->pseudo_palette = (void *) (par + 1); 788 - info->flags = FBINFO_DEFAULT; 789 - 790 - info->screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size); 791 - if (!info->screen_base) { 792 - printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n"); 793 - goto fail_ioremap_fbmem; 794 - } 795 - 796 - if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 797 - goto fail_color_map; 798 - 799 - if (register_framebuffer(info) < 0) { 800 - printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n"); 801 - goto fail_register_framebuffer; 802 - } 803 - 804 - platform_set_drvdata(dev, info); 805 - 806 - fb_info(info, "SGI DBE frame buffer device, using %ldK of video memory at %#lx\n", 807 - sgivwfb_mem_size >> 10, sgivwfb_mem_phys); 808 - return 0; 809 - 810 - fail_register_framebuffer: 811 - fb_dealloc_cmap(&info->cmap); 812 - fail_color_map: 813 - iounmap((char *) info->screen_base); 814 - fail_ioremap_fbmem: 815 - iounmap(par->regs); 816 - fail_ioremap_regs: 817 - release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE); 818 - framebuffer_release(info); 819 - return -ENXIO; 820 - } 821 - 822 - static int sgivwfb_remove(struct platform_device *dev) 823 - { 824 - struct fb_info *info = platform_get_drvdata(dev); 825 - 826 - if (info) { 827 - struct sgivw_par *par = info->par; 828 - 829 - unregister_framebuffer(info); 830 - dbe_TurnOffDma(par); 831 - iounmap(par->regs); 832 - iounmap(info->screen_base); 833 - release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE); 834 - fb_dealloc_cmap(&info->cmap); 835 - framebuffer_release(info); 836 - } 837 - return 0; 838 - } 839 - 840 - static struct platform_driver sgivwfb_driver = { 841 - .probe = sgivwfb_probe, 842 - .remove = sgivwfb_remove, 843 - .driver = { 844 - .name = "sgivwfb", 845 - }, 846 - }; 847 - 848 - static struct platform_device *sgivwfb_device; 849 - 850 - int __init sgivwfb_init(void) 851 - { 852 - int ret; 853 - 854 - #ifndef MODULE 855 - char *option = NULL; 856 - 857 - if (fb_get_options("sgivwfb", &option)) 858 - return -ENODEV; 859 - sgivwfb_setup(option); 860 - #endif 861 - ret = platform_driver_register(&sgivwfb_driver); 862 - if (!ret) { 863 - sgivwfb_device = platform_device_alloc("sgivwfb", 0); 864 - if (sgivwfb_device) { 865 - ret = platform_device_add(sgivwfb_device); 866 - } else 867 - ret = -ENOMEM; 868 - if (ret) { 869 - platform_driver_unregister(&sgivwfb_driver); 870 - platform_device_put(sgivwfb_device); 871 - } 872 - } 873 - return ret; 874 - } 875 - 876 - module_init(sgivwfb_init); 877 - 878 - #ifdef MODULE 879 - MODULE_LICENSE("GPL"); 880 - 881 - static void __exit sgivwfb_exit(void) 882 - { 883 - platform_device_unregister(sgivwfb_device); 884 - platform_driver_unregister(&sgivwfb_driver); 885 - } 886 - 887 - module_exit(sgivwfb_exit); 888 - 889 - #endif /* MODULE */
-681
include/video/sgivw.h
··· 1 - /* 2 - * linux/drivers/video/sgivw.h -- SGI DBE frame buffer device header 3 - * 4 - * Copyright (C) 1999 Silicon Graphics, Inc. 5 - * Jeffrey Newquist, newquist@engr.sgi.som 6 - * 7 - * This file is subject to the terms and conditions of the GNU General Public 8 - * License. See the file COPYING in the main directory of this archive for 9 - * more details. 10 - */ 11 - 12 - #ifndef __SGIVWFB_H__ 13 - #define __SGIVWFB_H__ 14 - 15 - #define DBE_GETREG(reg, dest) ((dest) = DBE_REG_BASE->reg) 16 - #define DBE_SETREG(reg, src) DBE_REG_BASE->reg = (src) 17 - #define DBE_IGETREG(reg, idx, dest) ((dest) = DBE_REG_BASE->reg[idx]) 18 - #define DBE_ISETREG(reg, idx, src) (DBE_REG_BASE->reg[idx] = (src)) 19 - 20 - #define MASK(msb, lsb) ( (((u32)1<<((msb)-(lsb)+1))-1) << (lsb) ) 21 - #define GET(v, msb, lsb) ( ((u32)(v) & MASK(msb,lsb)) >> (lsb) ) 22 - #define SET(v, f, msb, lsb) ( (v) = ((v)&~MASK(msb,lsb)) | (( (u32)(f)<<(lsb) ) & MASK(msb,lsb)) ) 23 - 24 - #define GET_DBE_FIELD(reg, field, v) GET((v), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB) 25 - #define SET_DBE_FIELD(reg, field, v, f) SET((v), (f), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB) 26 - 27 - /* NOTE: All loads/stores must be 32 bits and uncached */ 28 - 29 - #define DBE_REG_PHYS 0xd0000000 30 - #define DBE_REG_SIZE 0x01000000 31 - 32 - struct asregs { 33 - volatile u32 ctrlstat; /* 0x000000 general control */ 34 - volatile u32 dotclock; /* 0x000004 dot clock PLL control */ 35 - volatile u32 i2c; /* 0x000008 crt I2C control */ 36 - volatile u32 sysclk; /* 0x00000c system clock PLL control */ 37 - volatile u32 i2cfp; /* 0x000010 flat panel I2C control */ 38 - volatile u32 id; /* 0x000014 device id/chip revision */ 39 - volatile u32 config; /* 0x000018 power on configuration */ 40 - volatile u32 bist; /* 0x00001c internal bist status */ 41 - 42 - char _pad0[ 0x010000 - 0x000020 ]; 43 - 44 - volatile u32 vt_xy; /* 0x010000 current dot coords */ 45 - volatile u32 vt_xymax; /* 0x010004 maximum dot coords */ 46 - volatile u32 vt_vsync; /* 0x010008 vsync on/off */ 47 - volatile u32 vt_hsync; /* 0x01000c hsync on/off */ 48 - volatile u32 vt_vblank; /* 0x010010 vblank on/off */ 49 - volatile u32 vt_hblank; /* 0x010014 hblank on/off */ 50 - volatile u32 vt_flags; /* 0x010018 polarity of vt signals */ 51 - volatile u32 vt_f2rf_lock; /* 0x01001c f2rf & framelck y coord */ 52 - volatile u32 vt_intr01; /* 0x010020 intr 0,1 y coords */ 53 - volatile u32 vt_intr23; /* 0x010024 intr 2,3 y coords */ 54 - volatile u32 fp_hdrv; /* 0x010028 flat panel hdrv on/off */ 55 - volatile u32 fp_vdrv; /* 0x01002c flat panel vdrv on/off */ 56 - volatile u32 fp_de; /* 0x010030 flat panel de on/off */ 57 - volatile u32 vt_hpixen; /* 0x010034 intrnl horiz pixel on/off*/ 58 - volatile u32 vt_vpixen; /* 0x010038 intrnl vert pixel on/off */ 59 - volatile u32 vt_hcmap; /* 0x01003c cmap write (horiz) */ 60 - volatile u32 vt_vcmap; /* 0x010040 cmap write (vert) */ 61 - volatile u32 did_start_xy; /* 0x010044 eol/f did/xy reset val */ 62 - volatile u32 crs_start_xy; /* 0x010048 eol/f crs/xy reset val */ 63 - volatile u32 vc_start_xy; /* 0x01004c eol/f vc/xy reset val */ 64 - 65 - char _pad1[ 0x020000 - 0x010050 ]; 66 - 67 - volatile u32 ovr_width_tile; /* 0x020000 overlay plane ctrl 0 */ 68 - volatile u32 ovr_inhwctrl; /* 0x020004 overlay plane ctrl 1 */ 69 - volatile u32 ovr_control; /* 0x020008 overlay plane ctrl 1 */ 70 - 71 - char _pad2[ 0x030000 - 0x02000C ]; 72 - 73 - volatile u32 frm_size_tile; /* 0x030000 normal plane ctrl 0 */ 74 - volatile u32 frm_size_pixel; /* 0x030004 normal plane ctrl 1 */ 75 - volatile u32 frm_inhwctrl; /* 0x030008 normal plane ctrl 2 */ 76 - volatile u32 frm_control; /* 0x03000C normal plane ctrl 3 */ 77 - 78 - char _pad3[ 0x040000 - 0x030010 ]; 79 - 80 - volatile u32 did_inhwctrl; /* 0x040000 DID control */ 81 - volatile u32 did_control; /* 0x040004 DID shadow */ 82 - 83 - char _pad4[ 0x048000 - 0x040008 ]; 84 - 85 - volatile u32 mode_regs[32]; /* 0x048000 - 0x04807c WID table */ 86 - 87 - char _pad5[ 0x050000 - 0x048080 ]; 88 - 89 - volatile u32 cmap[6144]; /* 0x050000 - 0x055ffc color map */ 90 - 91 - char _pad6[ 0x058000 - 0x056000 ]; 92 - 93 - volatile u32 cm_fifo; /* 0x058000 color map fifo status */ 94 - 95 - char _pad7[ 0x060000 - 0x058004 ]; 96 - 97 - volatile u32 gmap[256]; /* 0x060000 - 0x0603fc gamma map */ 98 - 99 - char _pad8[ 0x068000 - 0x060400 ]; 100 - 101 - volatile u32 gmap10[1024]; /* 0x068000 - 0x068ffc gamma map */ 102 - 103 - char _pad9[ 0x070000 - 0x069000 ]; 104 - 105 - volatile u32 crs_pos; /* 0x070000 cusror control 0 */ 106 - volatile u32 crs_ctl; /* 0x070004 cusror control 1 */ 107 - volatile u32 crs_cmap[3]; /* 0x070008 - 0x070010 crs cmap */ 108 - 109 - char _pad10[ 0x078000 - 0x070014 ]; 110 - 111 - volatile u32 crs_glyph[64]; /* 0x078000 - 0x0780fc crs glyph */ 112 - 113 - char _pad11[ 0x080000 - 0x078100 ]; 114 - 115 - volatile u32 vc_0; /* 0x080000 video capture crtl 0 */ 116 - volatile u32 vc_1; /* 0x080004 video capture crtl 1 */ 117 - volatile u32 vc_2; /* 0x080008 video capture crtl 2 */ 118 - volatile u32 vc_3; /* 0x08000c video capture crtl 3 */ 119 - volatile u32 vc_4; /* 0x080010 video capture crtl 3 */ 120 - volatile u32 vc_5; /* 0x080014 video capture crtl 3 */ 121 - volatile u32 vc_6; /* 0x080018 video capture crtl 3 */ 122 - volatile u32 vc_7; /* 0x08001c video capture crtl 3 */ 123 - volatile u32 vc_8; /* 0x08000c video capture crtl 3 */ 124 - }; 125 - 126 - /* Bit mask information */ 127 - 128 - #define DBE_CTRLSTAT_CHIPID_MSB 3 129 - #define DBE_CTRLSTAT_CHIPID_LSB 0 130 - #define DBE_CTRLSTAT_SENSE_N_MSB 4 131 - #define DBE_CTRLSTAT_SENSE_N_LSB 4 132 - #define DBE_CTRLSTAT_PCLKSEL_MSB 29 133 - #define DBE_CTRLSTAT_PCLKSEL_LSB 28 134 - 135 - #define DBE_DOTCLK_M_MSB 7 136 - #define DBE_DOTCLK_M_LSB 0 137 - #define DBE_DOTCLK_N_MSB 13 138 - #define DBE_DOTCLK_N_LSB 8 139 - #define DBE_DOTCLK_P_MSB 15 140 - #define DBE_DOTCLK_P_LSB 14 141 - #define DBE_DOTCLK_RUN_MSB 20 142 - #define DBE_DOTCLK_RUN_LSB 20 143 - 144 - #define DBE_VT_XY_VT_FREEZE_MSB 31 145 - #define DBE_VT_XY_VT_FREEZE_LSB 31 146 - 147 - #define DBE_FP_VDRV_FP_VDRV_ON_MSB 23 148 - #define DBE_FP_VDRV_FP_VDRV_ON_LSB 12 149 - #define DBE_FP_VDRV_FP_VDRV_OFF_MSB 11 150 - #define DBE_FP_VDRV_FP_VDRV_OFF_LSB 0 151 - 152 - #define DBE_FP_HDRV_FP_HDRV_ON_MSB 23 153 - #define DBE_FP_HDRV_FP_HDRV_ON_LSB 12 154 - #define DBE_FP_HDRV_FP_HDRV_OFF_MSB 11 155 - #define DBE_FP_HDRV_FP_HDRV_OFF_LSB 0 156 - 157 - #define DBE_FP_DE_FP_DE_ON_MSB 23 158 - #define DBE_FP_DE_FP_DE_ON_LSB 12 159 - #define DBE_FP_DE_FP_DE_OFF_MSB 11 160 - #define DBE_FP_DE_FP_DE_OFF_LSB 0 161 - 162 - #define DBE_VT_VSYNC_VT_VSYNC_ON_MSB 23 163 - #define DBE_VT_VSYNC_VT_VSYNC_ON_LSB 12 164 - #define DBE_VT_VSYNC_VT_VSYNC_OFF_MSB 11 165 - #define DBE_VT_VSYNC_VT_VSYNC_OFF_LSB 0 166 - 167 - #define DBE_VT_HSYNC_VT_HSYNC_ON_MSB 23 168 - #define DBE_VT_HSYNC_VT_HSYNC_ON_LSB 12 169 - #define DBE_VT_HSYNC_VT_HSYNC_OFF_MSB 11 170 - #define DBE_VT_HSYNC_VT_HSYNC_OFF_LSB 0 171 - 172 - #define DBE_VT_VBLANK_VT_VBLANK_ON_MSB 23 173 - #define DBE_VT_VBLANK_VT_VBLANK_ON_LSB 12 174 - #define DBE_VT_VBLANK_VT_VBLANK_OFF_MSB 11 175 - #define DBE_VT_VBLANK_VT_VBLANK_OFF_LSB 0 176 - 177 - #define DBE_VT_HBLANK_VT_HBLANK_ON_MSB 23 178 - #define DBE_VT_HBLANK_VT_HBLANK_ON_LSB 12 179 - #define DBE_VT_HBLANK_VT_HBLANK_OFF_MSB 11 180 - #define DBE_VT_HBLANK_VT_HBLANK_OFF_LSB 0 181 - 182 - #define DBE_VT_FLAGS_VDRV_INVERT_MSB 0 183 - #define DBE_VT_FLAGS_VDRV_INVERT_LSB 0 184 - #define DBE_VT_FLAGS_HDRV_INVERT_MSB 2 185 - #define DBE_VT_FLAGS_HDRV_INVERT_LSB 2 186 - 187 - #define DBE_VT_VCMAP_VT_VCMAP_ON_MSB 23 188 - #define DBE_VT_VCMAP_VT_VCMAP_ON_LSB 12 189 - #define DBE_VT_VCMAP_VT_VCMAP_OFF_MSB 11 190 - #define DBE_VT_VCMAP_VT_VCMAP_OFF_LSB 0 191 - 192 - #define DBE_VT_HCMAP_VT_HCMAP_ON_MSB 23 193 - #define DBE_VT_HCMAP_VT_HCMAP_ON_LSB 12 194 - #define DBE_VT_HCMAP_VT_HCMAP_OFF_MSB 11 195 - #define DBE_VT_HCMAP_VT_HCMAP_OFF_LSB 0 196 - 197 - #define DBE_VT_XYMAX_VT_MAXX_MSB 11 198 - #define DBE_VT_XYMAX_VT_MAXX_LSB 0 199 - #define DBE_VT_XYMAX_VT_MAXY_MSB 23 200 - #define DBE_VT_XYMAX_VT_MAXY_LSB 12 201 - 202 - #define DBE_VT_HPIXEN_VT_HPIXEN_ON_MSB 23 203 - #define DBE_VT_HPIXEN_VT_HPIXEN_ON_LSB 12 204 - #define DBE_VT_HPIXEN_VT_HPIXEN_OFF_MSB 11 205 - #define DBE_VT_HPIXEN_VT_HPIXEN_OFF_LSB 0 206 - 207 - #define DBE_VT_VPIXEN_VT_VPIXEN_ON_MSB 23 208 - #define DBE_VT_VPIXEN_VT_VPIXEN_ON_LSB 12 209 - #define DBE_VT_VPIXEN_VT_VPIXEN_OFF_MSB 11 210 - #define DBE_VT_VPIXEN_VT_VPIXEN_OFF_LSB 0 211 - 212 - #define DBE_OVR_CONTROL_OVR_DMA_ENABLE_MSB 0 213 - #define DBE_OVR_CONTROL_OVR_DMA_ENABLE_LSB 0 214 - 215 - #define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_MSB 0 216 - #define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_LSB 0 217 - 218 - #define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_MSB 13 219 - #define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_LSB 13 220 - 221 - #define DBE_FRM_CONTROL_FRM_DMA_ENABLE_MSB 0 222 - #define DBE_FRM_CONTROL_FRM_DMA_ENABLE_LSB 0 223 - #define DBE_FRM_CONTROL_FRM_TILE_PTR_MSB 31 224 - #define DBE_FRM_CONTROL_FRM_TILE_PTR_LSB 9 225 - #define DBE_FRM_CONTROL_FRM_LINEAR_MSB 1 226 - #define DBE_FRM_CONTROL_FRM_LINEAR_LSB 1 227 - 228 - #define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_MSB 0 229 - #define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_LSB 0 230 - 231 - #define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_MSB 12 232 - #define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_LSB 5 233 - #define DBE_FRM_SIZE_TILE_FRM_RHS_MSB 4 234 - #define DBE_FRM_SIZE_TILE_FRM_RHS_LSB 0 235 - #define DBE_FRM_SIZE_TILE_FRM_DEPTH_MSB 14 236 - #define DBE_FRM_SIZE_TILE_FRM_DEPTH_LSB 13 237 - #define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_MSB 15 238 - #define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_LSB 15 239 - 240 - #define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_MSB 31 241 - #define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_LSB 16 242 - 243 - #define DBE_DID_CONTROL_DID_DMA_ENABLE_MSB 0 244 - #define DBE_DID_CONTROL_DID_DMA_ENABLE_LSB 0 245 - #define DBE_DID_INHWCTRL_DID_DMA_ENABLE_MSB 0 246 - #define DBE_DID_INHWCTRL_DID_DMA_ENABLE_LSB 0 247 - 248 - #define DBE_DID_START_XY_DID_STARTY_MSB 23 249 - #define DBE_DID_START_XY_DID_STARTY_LSB 12 250 - #define DBE_DID_START_XY_DID_STARTX_MSB 11 251 - #define DBE_DID_START_XY_DID_STARTX_LSB 0 252 - 253 - #define DBE_CRS_START_XY_CRS_STARTY_MSB 23 254 - #define DBE_CRS_START_XY_CRS_STARTY_LSB 12 255 - #define DBE_CRS_START_XY_CRS_STARTX_MSB 11 256 - #define DBE_CRS_START_XY_CRS_STARTX_LSB 0 257 - 258 - #define DBE_WID_TYP_MSB 4 259 - #define DBE_WID_TYP_LSB 2 260 - #define DBE_WID_BUF_MSB 1 261 - #define DBE_WID_BUF_LSB 0 262 - 263 - #define DBE_VC_START_XY_VC_STARTY_MSB 23 264 - #define DBE_VC_START_XY_VC_STARTY_LSB 12 265 - #define DBE_VC_START_XY_VC_STARTX_MSB 11 266 - #define DBE_VC_START_XY_VC_STARTX_LSB 0 267 - 268 - /* Constants */ 269 - 270 - #define DBE_FRM_DEPTH_8 0 271 - #define DBE_FRM_DEPTH_16 1 272 - #define DBE_FRM_DEPTH_32 2 273 - 274 - #define DBE_CMODE_I8 0 275 - #define DBE_CMODE_I12 1 276 - #define DBE_CMODE_RG3B2 2 277 - #define DBE_CMODE_RGB4 3 278 - #define DBE_CMODE_ARGB5 4 279 - #define DBE_CMODE_RGB8 5 280 - #define DBE_CMODE_RGBA5 6 281 - #define DBE_CMODE_RGB10 7 282 - 283 - #define DBE_BMODE_BOTH 3 284 - 285 - #define DBE_CRS_MAGIC 54 286 - 287 - #define DBE_CLOCK_REF_KHZ 27000 288 - 289 - /* Config Register (DBE Only) Definitions */ 290 - 291 - #define DBE_CONFIG_VDAC_ENABLE 0x00000001 292 - #define DBE_CONFIG_VDAC_GSYNC 0x00000002 293 - #define DBE_CONFIG_VDAC_PBLANK 0x00000004 294 - #define DBE_CONFIG_FPENABLE 0x00000008 295 - #define DBE_CONFIG_LENDIAN 0x00000020 296 - #define DBE_CONFIG_TILEHIST 0x00000040 297 - #define DBE_CONFIG_EXT_ADDR 0x00000080 298 - 299 - #define DBE_CONFIG_FBDEV ( DBE_CONFIG_VDAC_ENABLE | \ 300 - DBE_CONFIG_VDAC_GSYNC | \ 301 - DBE_CONFIG_VDAC_PBLANK | \ 302 - DBE_CONFIG_LENDIAN | \ 303 - DBE_CONFIG_EXT_ADDR ) 304 - 305 - /* 306 - * Available Video Timings and Corresponding Indices 307 - */ 308 - 309 - typedef enum { 310 - DBE_VT_640_480_60, 311 - 312 - DBE_VT_800_600_60, 313 - DBE_VT_800_600_75, 314 - DBE_VT_800_600_120, 315 - 316 - DBE_VT_1024_768_50, 317 - DBE_VT_1024_768_60, 318 - DBE_VT_1024_768_75, 319 - DBE_VT_1024_768_85, 320 - DBE_VT_1024_768_120, 321 - 322 - DBE_VT_1280_1024_50, 323 - DBE_VT_1280_1024_60, 324 - DBE_VT_1280_1024_75, 325 - DBE_VT_1280_1024_85, 326 - 327 - DBE_VT_1600_1024_53, 328 - DBE_VT_1600_1024_60, 329 - 330 - DBE_VT_1600_1200_50, 331 - DBE_VT_1600_1200_60, 332 - DBE_VT_1600_1200_75, 333 - 334 - DBE_VT_1920_1080_50, 335 - DBE_VT_1920_1080_60, 336 - DBE_VT_1920_1080_72, 337 - 338 - DBE_VT_1920_1200_50, 339 - DBE_VT_1920_1200_60, 340 - DBE_VT_1920_1200_66, 341 - 342 - DBE_VT_UNKNOWN 343 - } dbe_timing_t; 344 - 345 - 346 - 347 - /* 348 - * Crime Video Timing Data Structure 349 - */ 350 - 351 - struct dbe_timing_info 352 - { 353 - dbe_timing_t type; 354 - int flags; 355 - short width; /* Monitor resolution */ 356 - short height; 357 - int fields_sec; /* fields/sec (Hz -3 dec. places */ 358 - int cfreq; /* pixel clock frequency (MHz -3 dec. places) */ 359 - short htotal; /* Horizontal total pixels */ 360 - short hblank_start; /* Horizontal blank start */ 361 - short hblank_end; /* Horizontal blank end */ 362 - short hsync_start; /* Horizontal sync start */ 363 - short hsync_end; /* Horizontal sync end */ 364 - short vtotal; /* Vertical total lines */ 365 - short vblank_start; /* Vertical blank start */ 366 - short vblank_end; /* Vertical blank end */ 367 - short vsync_start; /* Vertical sync start */ 368 - short vsync_end; /* Vertical sync end */ 369 - short pll_m; /* PLL M parameter */ 370 - short pll_n; /* PLL P parameter */ 371 - short pll_p; /* PLL N parameter */ 372 - }; 373 - 374 - /* Defines for dbe_vof_info_t flags */ 375 - 376 - #define DBE_VOF_UNKNOWNMON 1 377 - #define DBE_VOF_STEREO 2 378 - #define DBE_VOF_DO_GENSYNC 4 /* enable incoming sync */ 379 - #define DBE_VOF_SYNC_ON_GREEN 8 /* sync on green */ 380 - #define DBE_VOF_FLATPANEL 0x1000 /* FLATPANEL Timing */ 381 - #define DBE_VOF_MAGICKEY 0x2000 /* Backdoor key */ 382 - 383 - /* 384 - * DBE Timing Tables 385 - */ 386 - 387 - #ifdef INCLUDE_TIMING_TABLE_DATA 388 - struct dbe_timing_info dbeVTimings[] = { 389 - { 390 - DBE_VT_640_480_60, 391 - /* flags, width, height, fields_sec, cfreq */ 392 - 0, 640, 480, 59940, 25175, 393 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 394 - 800, 640, 800, 656, 752, 395 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 396 - 525, 480, 525, 490, 492, 397 - /* pll_m, pll_n, pll_p */ 398 - 15, 2, 3 399 - }, 400 - 401 - { 402 - DBE_VT_800_600_60, 403 - /* flags, width, height, fields_sec, cfreq */ 404 - 0, 800, 600, 60317, 40000, 405 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 406 - 1056, 800, 1056, 840, 968, 407 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 408 - 628, 600, 628, 601, 605, 409 - /* pll_m, pll_n, pll_p */ 410 - 3, 1, 1 411 - }, 412 - 413 - { 414 - DBE_VT_800_600_75, 415 - /* flags, width, height, fields_sec, cfreq */ 416 - 0, 800, 600, 75000, 49500, 417 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 418 - 1056, 800, 1056, 816, 896, 419 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 420 - 625, 600, 625, 601, 604, 421 - /* pll_m, pll_n, pll_p */ 422 - 11, 3, 1 423 - }, 424 - 425 - { 426 - DBE_VT_800_600_120, 427 - /* flags, width, height, fields_sec, cfreq */ 428 - DBE_VOF_STEREO, 800, 600, 119800, 82978, 429 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 430 - 1040, 800, 1040, 856, 976, 431 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 432 - 666, 600, 666, 637, 643, 433 - /* pll_m, pll_n, pll_p */ 434 - 31, 5, 1 435 - }, 436 - 437 - { 438 - DBE_VT_1024_768_50, 439 - /* flags, width, height, fields_sec, cfreq */ 440 - 0, 1024, 768, 50000, 54163, 441 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 442 - 1344, 1024, 1344, 1048, 1184, 443 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 444 - 806, 768, 806, 771, 777, 445 - /* pll_m, pll_n, pll_p */ 446 - 4, 1, 1 447 - }, 448 - 449 - { 450 - DBE_VT_1024_768_60, 451 - /* flags, width, height, fields_sec, cfreq */ 452 - 0, 1024, 768, 60004, 65000, 453 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 454 - 1344, 1024, 1344, 1048, 1184, 455 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 456 - 806, 768, 806, 771, 777, 457 - /* pll_m, pll_n, pll_p */ 458 - 12, 5, 0 459 - }, 460 - 461 - { 462 - DBE_VT_1024_768_75, 463 - /* flags, width, height, fields_sec, cfreq */ 464 - 0, 1024, 768, 75029, 78750, 465 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 466 - 1312, 1024, 1312, 1040, 1136, 467 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 468 - 800, 768, 800, 769, 772, 469 - /* pll_m, pll_n, pll_p */ 470 - 29, 5, 1 471 - }, 472 - 473 - { 474 - DBE_VT_1024_768_85, 475 - /* flags, width, height, fields_sec, cfreq */ 476 - 0, 1024, 768, 84997, 94500, 477 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 478 - 1376, 1024, 1376, 1072, 1168, 479 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 480 - 808, 768, 808, 769, 772, 481 - /* pll_m, pll_n, pll_p */ 482 - 7, 2, 0 483 - }, 484 - 485 - { 486 - DBE_VT_1024_768_120, 487 - /* flags, width, height, fields_sec, cfreq */ 488 - DBE_VOF_STEREO, 1024, 768, 119800, 133195, 489 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 490 - 1376, 1024, 1376, 1072, 1168, 491 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 492 - 808, 768, 808, 769, 772, 493 - /* pll_m, pll_n, pll_p */ 494 - 5, 1, 0 495 - }, 496 - 497 - { 498 - DBE_VT_1280_1024_50, 499 - /* flags, width, height, fields_sec, cfreq */ 500 - 0, 1280, 1024, 50000, 89460, 501 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 502 - 1680, 1280, 1680, 1360, 1480, 503 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 504 - 1065, 1024, 1065, 1027, 1030, 505 - /* pll_m, pll_n, pll_p */ 506 - 10, 3, 0 507 - }, 508 - 509 - { 510 - DBE_VT_1280_1024_60, 511 - /* flags, width, height, fields_sec, cfreq */ 512 - 0, 1280, 1024, 60020, 108000, 513 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 514 - 1688, 1280, 1688, 1328, 1440, 515 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 516 - 1066, 1024, 1066, 1025, 1028, 517 - /* pll_m, pll_n, pll_p */ 518 - 4, 1, 0 519 - }, 520 - 521 - { 522 - DBE_VT_1280_1024_75, 523 - /* flags, width, height, fields_sec, cfreq */ 524 - 0, 1280, 1024, 75025, 135000, 525 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 526 - 1688, 1280, 1688, 1296, 1440, 527 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 528 - 1066, 1024, 1066, 1025, 1028, 529 - /* pll_m, pll_n, pll_p */ 530 - 5, 1, 0 531 - }, 532 - 533 - { 534 - DBE_VT_1280_1024_85, 535 - /* flags, width, height, fields_sec, cfreq */ 536 - 0, 1280, 1024, 85024, 157500, 537 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 538 - 1728, 1280, 1728, 1344, 1504, 539 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 540 - 1072, 1024, 1072, 1025, 1028, 541 - /* pll_m, pll_n, pll_p */ 542 - 29, 5, 0 543 - }, 544 - 545 - { 546 - DBE_VT_1600_1024_53, 547 - /* flags, width, height, fields_sec, cfreq */ 548 - DBE_VOF_FLATPANEL | DBE_VOF_MAGICKEY, 549 - 1600, 1024, 53000, 107447, 550 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 551 - 1900, 1600, 1900, 1630, 1730, 552 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 553 - 1067, 1024, 1067, 1027, 1030, 554 - /* pll_m, pll_n, pll_p */ 555 - 4, 1, 0 556 - }, 557 - 558 - { 559 - DBE_VT_1600_1024_60, 560 - /* flags, width, height, fields_sec, cfreq */ 561 - DBE_VOF_FLATPANEL, 1600, 1024, 60000, 106913, 562 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 563 - 1670, 1600, 1670, 1630, 1650, 564 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 565 - 1067, 1024, 1067, 1027, 1030, 566 - /* pll_m, pll_n, pll_p */ 567 - 4, 1, 0 568 - }, 569 - 570 - { 571 - DBE_VT_1600_1200_50, 572 - /* flags, width, height, fields_sec, cfreq */ 573 - 0, 1600, 1200, 50000, 130500, 574 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 575 - 2088, 1600, 2088, 1644, 1764, 576 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 577 - 1250, 1200, 1250, 1205, 1211, 578 - /* pll_m, pll_n, pll_p */ 579 - 24, 5, 0 580 - }, 581 - 582 - { 583 - DBE_VT_1600_1200_60, 584 - /* flags, width, height, fields_sec, cfreq */ 585 - 0, 1600, 1200, 59940, 162000, 586 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 587 - 2160, 1600, 2160, 1644, 1856, 588 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 589 - 1250, 1200, 1250, 1201, 1204, 590 - /* pll_m, pll_n, pll_p */ 591 - 6, 1, 0 592 - }, 593 - 594 - { 595 - DBE_VT_1600_1200_75, 596 - /* flags, width, height, fields_sec, cfreq */ 597 - 0, 1600, 1200, 75000, 202500, 598 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 599 - 2160, 1600, 2160, 1644, 1856, 600 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 601 - 1250, 1200, 1250, 1201, 1204, 602 - /* pll_m, pll_n, pll_p */ 603 - 15, 2, 0 604 - }, 605 - 606 - { 607 - DBE_VT_1920_1080_50, 608 - /* flags, width, height, fields_sec, cfreq */ 609 - 0, 1920, 1080, 50000, 133200, 610 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 611 - 2368, 1920, 2368, 1952, 2096, 612 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 613 - 1125, 1080, 1125, 1083, 1086, 614 - /* pll_m, pll_n, pll_p */ 615 - 5, 1, 0 616 - }, 617 - 618 - { 619 - DBE_VT_1920_1080_60, 620 - /* flags, width, height, fields_sec, cfreq */ 621 - 0, 1920, 1080, 59940, 159840, 622 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 623 - 2368, 1920, 2368, 1952, 2096, 624 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 625 - 1125, 1080, 1125, 1083, 1086, 626 - /* pll_m, pll_n, pll_p */ 627 - 6, 1, 0 628 - }, 629 - 630 - { 631 - DBE_VT_1920_1080_72, 632 - /* flags, width, height, fields_sec, cfreq */ 633 - 0, 1920, 1080, 72000, 216023, 634 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 635 - 2560, 1920, 2560, 1968, 2184, 636 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 637 - 1172, 1080, 1172, 1083, 1086, 638 - /* pll_m, pll_n, pll_p */ 639 - 8, 1, 0 640 - }, 641 - 642 - { 643 - DBE_VT_1920_1200_50, 644 - /* flags, width, height, fields_sec, cfreq */ 645 - 0, 1920, 1200, 50000, 161500, 646 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 647 - 2584, 1920, 2584, 1984, 2240, 648 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 649 - 1250, 1200, 1250, 1203, 1206, 650 - /* pll_m, pll_n, pll_p */ 651 - 6, 1, 0 652 - }, 653 - 654 - { 655 - DBE_VT_1920_1200_60, 656 - /* flags, width, height, fields_sec, cfreq */ 657 - 0, 1920, 1200, 59940, 193800, 658 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 659 - 2584, 1920, 2584, 1984, 2240, 660 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 661 - 1250, 1200, 1250, 1203, 1206, 662 - /* pll_m, pll_n, pll_p */ 663 - 29, 4, 0 664 - }, 665 - 666 - { 667 - DBE_VT_1920_1200_66, 668 - /* flags, width, height, fields_sec, cfreq */ 669 - 0, 1920, 1200, 66000, 213180, 670 - /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */ 671 - 2584, 1920, 2584, 1984, 2240, 672 - /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */ 673 - 1250, 1200, 1250, 1203, 1206, 674 - /* pll_m, pll_n, pll_p */ 675 - 8, 1, 0 676 - } 677 - }; 678 - 679 - #endif // INCLUDE_TIMING_TABLE_DATA 680 - 681 - #endif // ! __SGIVWFB_H__
-9
sound/oss/Kconfig
··· 13 13 note that CONFIG_KGDB should not be enabled at the same 14 14 time, since it also attempts to use this UART port. 15 15 16 - config SOUND_VWSND 17 - tristate "SGI Visual Workstation Sound" 18 - depends on X86_VISWS 19 - help 20 - Say Y or M if you have an SGI Visual Workstation and you want to be 21 - able to use its on-board audio. Read 22 - <file:Documentation/sound/oss/vwsnd> for more info on this driver's 23 - capabilities. 24 - 25 16 config SOUND_MSNDCLAS 26 17 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" 27 18 depends on (m || !STANDALONE) && ISA
-1
sound/oss/Makefile
··· 24 24 obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o 25 25 obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o 26 26 obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o 27 - obj-$(CONFIG_SOUND_VWSND) += vwsnd.o 28 27 obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o 29 28 30 29 obj-$(CONFIG_DMASOUND) += dmasound/
-3506
sound/oss/vwsnd.c
··· 1 - /* 2 - * Sound driver for Silicon Graphics 320 and 540 Visual Workstations' 3 - * onboard audio. See notes in Documentation/sound/oss/vwsnd . 4 - * 5 - * Copyright 1999 Silicon Graphics, Inc. All rights reserved. 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License as published by 9 - * the Free Software Foundation; either version 2 of the License, or 10 - * (at your option) any later version. 11 - * 12 - * This program is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - * GNU General Public License for more details. 16 - * 17 - * You should have received a copy of the GNU General Public License 18 - * along with this program; if not, write to the Free Software 19 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 - */ 21 - 22 - #undef VWSND_DEBUG /* define for debugging */ 23 - 24 - /* 25 - * XXX to do - 26 - * 27 - * External sync. 28 - * Rename swbuf, hwbuf, u&i, hwptr&swptr to something rational. 29 - * Bug - if select() called before read(), pcm_setup() not called. 30 - * Bug - output doesn't stop soon enough if process killed. 31 - */ 32 - 33 - /* 34 - * Things to test - 35 - * 36 - * Will readv/writev work? Write a test. 37 - * 38 - * insmod/rmmod 100 million times. 39 - * 40 - * Run I/O until int ptrs wrap around (roughly 6.2 hours @ DAT 41 - * rate). 42 - * 43 - * Concurrent threads banging on mixer simultaneously, both UP 44 - * and SMP kernels. Especially, watch for thread A changing 45 - * OUTSRC while thread B changes gain -- both write to the same 46 - * ad1843 register. 47 - * 48 - * What happens if a client opens /dev/audio then forks? 49 - * Do two procs have /dev/audio open? Test. 50 - * 51 - * Pump audio through the CD, MIC and line inputs and verify that 52 - * they mix/mute into the output. 53 - * 54 - * Apps: 55 - * amp 56 - * mpg123 57 - * x11amp 58 - * mxv 59 - * kmedia 60 - * esound 61 - * need more input apps 62 - * 63 - * Run tests while bombarding with signals. setitimer(2) will do it... */ 64 - 65 - /* 66 - * This driver is organized in nine sections. 67 - * The nine sections are: 68 - * 69 - * debug stuff 70 - * low level lithium access 71 - * high level lithium access 72 - * AD1843 access 73 - * PCM I/O 74 - * audio driver 75 - * mixer driver 76 - * probe/attach/unload 77 - * initialization and loadable kernel module interface 78 - * 79 - * That is roughly the order of increasing abstraction, so forward 80 - * dependencies are minimal. 81 - */ 82 - 83 - /* 84 - * Locking Notes 85 - * 86 - * INC_USE_COUNT and DEC_USE_COUNT keep track of the number of 87 - * open descriptors to this driver. They store it in vwsnd_use_count. 88 - * The global device list, vwsnd_dev_list, is immutable when the IN_USE 89 - * is true. 90 - * 91 - * devc->open_lock is a semaphore that is used to enforce the 92 - * single reader/single writer rule for /dev/audio. The rule is 93 - * that each device may have at most one reader and one writer. 94 - * Open will block until the previous client has closed the 95 - * device, unless O_NONBLOCK is specified. 96 - * 97 - * The semaphore devc->io_mutex serializes PCM I/O syscalls. This 98 - * is unnecessary in Linux 2.2, because the kernel lock 99 - * serializes read, write, and ioctl globally, but it's there, 100 - * ready for the brave, new post-kernel-lock world. 101 - * 102 - * Locking between interrupt and baselevel is handled by the 103 - * "lock" spinlock in vwsnd_port (one lock each for read and 104 - * write). Each half holds the lock just long enough to see what 105 - * area it owns and update its pointers. See pcm_output() and 106 - * pcm_input() for most of the gory stuff. 107 - * 108 - * devc->mix_mutex serializes all mixer ioctls. This is also 109 - * redundant because of the kernel lock. 110 - * 111 - * The lowest level lock is lith->lithium_lock. It is a 112 - * spinlock which is held during the two-register tango of 113 - * reading/writing an AD1843 register. See 114 - * li_{read,write}_ad1843_reg(). 115 - */ 116 - 117 - /* 118 - * Sample Format Notes 119 - * 120 - * Lithium's DMA engine has two formats: 16-bit 2's complement 121 - * and 8-bit unsigned . 16-bit transfers the data unmodified, 2 122 - * bytes per sample. 8-bit unsigned transfers 1 byte per sample 123 - * and XORs each byte with 0x80. Lithium can input or output 124 - * either mono or stereo in either format. 125 - * 126 - * The AD1843 has four formats: 16-bit 2's complement, 8-bit 127 - * unsigned, 8-bit mu-Law and 8-bit A-Law. 128 - * 129 - * This driver supports five formats: AFMT_S8, AFMT_U8, 130 - * AFMT_MU_LAW, AFMT_A_LAW, and AFMT_S16_LE. 131 - * 132 - * For AFMT_U8 output, we keep the AD1843 in 16-bit mode, and 133 - * rely on Lithium's XOR to translate between U8 and S8. 134 - * 135 - * For AFMT_S8, AFMT_MU_LAW and AFMT_A_LAW output, we have to XOR 136 - * the 0x80 bit in software to compensate for Lithium's XOR. 137 - * This happens in pcm_copy_{in,out}(). 138 - * 139 - * Changes: 140 - * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> 141 - * Added some __init/__exit 142 - */ 143 - 144 - #include <linux/module.h> 145 - #include <linux/init.h> 146 - 147 - #include <linux/spinlock.h> 148 - #include <linux/wait.h> 149 - #include <linux/interrupt.h> 150 - #include <linux/mutex.h> 151 - #include <linux/slab.h> 152 - #include <linux/delay.h> 153 - 154 - #include <asm/visws/cobalt.h> 155 - 156 - #include "sound_config.h" 157 - 158 - static DEFINE_MUTEX(vwsnd_mutex); 159 - 160 - /*****************************************************************************/ 161 - /* debug stuff */ 162 - 163 - #ifdef VWSND_DEBUG 164 - 165 - static int shut_up = 1; 166 - 167 - /* 168 - * dbgassert - called when an assertion fails. 169 - */ 170 - 171 - static void dbgassert(const char *fcn, int line, const char *expr) 172 - { 173 - if (in_interrupt()) 174 - panic("ASSERTION FAILED IN INTERRUPT, %s:%s:%d %s\n", 175 - __FILE__, fcn, line, expr); 176 - else { 177 - int x; 178 - printk(KERN_ERR "ASSERTION FAILED, %s:%s:%d %s\n", 179 - __FILE__, fcn, line, expr); 180 - x = * (volatile int *) 0; /* force proc to exit */ 181 - } 182 - } 183 - 184 - /* 185 - * Bunch of useful debug macros: 186 - * 187 - * ASSERT - print unless e nonzero (panic if in interrupt) 188 - * DBGDO - include arbitrary code if debugging 189 - * DBGX - debug print raw (w/o function name) 190 - * DBGP - debug print w/ function name 191 - * DBGE - debug print function entry 192 - * DBGC - debug print function call 193 - * DBGR - debug print function return 194 - * DBGXV - debug print raw when verbose 195 - * DBGPV - debug print when verbose 196 - * DBGEV - debug print function entry when verbose 197 - * DBGRV - debug print function return when verbose 198 - */ 199 - 200 - #define ASSERT(e) ((e) ? (void) 0 : dbgassert(__func__, __LINE__, #e)) 201 - #define DBGDO(x) x 202 - #define DBGX(fmt, args...) (in_interrupt() ? 0 : printk(KERN_ERR fmt, ##args)) 203 - #define DBGP(fmt, args...) (DBGX("%s: " fmt, __func__ , ##args)) 204 - #define DBGE(fmt, args...) (DBGX("%s" fmt, __func__ , ##args)) 205 - #define DBGC(rtn) (DBGP("calling %s\n", rtn)) 206 - #define DBGR() (DBGP("returning\n")) 207 - #define DBGXV(fmt, args...) (shut_up ? 0 : DBGX(fmt, ##args)) 208 - #define DBGPV(fmt, args...) (shut_up ? 0 : DBGP(fmt, ##args)) 209 - #define DBGEV(fmt, args...) (shut_up ? 0 : DBGE(fmt, ##args)) 210 - #define DBGCV(rtn) (shut_up ? 0 : DBGC(rtn)) 211 - #define DBGRV() (shut_up ? 0 : DBGR()) 212 - 213 - #else /* !VWSND_DEBUG */ 214 - 215 - #define ASSERT(e) ((void) 0) 216 - #define DBGDO(x) /* don't */ 217 - #define DBGX(fmt, args...) ((void) 0) 218 - #define DBGP(fmt, args...) ((void) 0) 219 - #define DBGE(fmt, args...) ((void) 0) 220 - #define DBGC(rtn) ((void) 0) 221 - #define DBGR() ((void) 0) 222 - #define DBGPV(fmt, args...) ((void) 0) 223 - #define DBGXV(fmt, args...) ((void) 0) 224 - #define DBGEV(fmt, args...) ((void) 0) 225 - #define DBGCV(rtn) ((void) 0) 226 - #define DBGRV() ((void) 0) 227 - 228 - #endif /* !VWSND_DEBUG */ 229 - 230 - /*****************************************************************************/ 231 - /* low level lithium access */ 232 - 233 - /* 234 - * We need to talk to Lithium registers on three pages. Here are 235 - * the pages' offsets from the base address (0xFF001000). 236 - */ 237 - 238 - enum { 239 - LI_PAGE0_OFFSET = 0x01000 - 0x1000, /* FF001000 */ 240 - LI_PAGE1_OFFSET = 0x0F000 - 0x1000, /* FF00F000 */ 241 - LI_PAGE2_OFFSET = 0x10000 - 0x1000, /* FF010000 */ 242 - }; 243 - 244 - /* low-level lithium data */ 245 - 246 - typedef struct lithium { 247 - void * page0; /* virtual addresses */ 248 - void * page1; 249 - void * page2; 250 - spinlock_t lock; /* protects codec and UST/MSC access */ 251 - } lithium_t; 252 - 253 - /* 254 - * li_destroy destroys the lithium_t structure and vm mappings. 255 - */ 256 - 257 - static void li_destroy(lithium_t *lith) 258 - { 259 - if (lith->page0) { 260 - iounmap(lith->page0); 261 - lith->page0 = NULL; 262 - } 263 - if (lith->page1) { 264 - iounmap(lith->page1); 265 - lith->page1 = NULL; 266 - } 267 - if (lith->page2) { 268 - iounmap(lith->page2); 269 - lith->page2 = NULL; 270 - } 271 - } 272 - 273 - /* 274 - * li_create initializes the lithium_t structure and sets up vm mappings 275 - * to access the registers. 276 - * Returns 0 on success, -errno on failure. 277 - */ 278 - 279 - static int __init li_create(lithium_t *lith, unsigned long baseaddr) 280 - { 281 - spin_lock_init(&lith->lock); 282 - lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE); 283 - lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE); 284 - lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE); 285 - if (!lith->page0 || !lith->page1 || !lith->page2) { 286 - li_destroy(lith); 287 - return -ENOMEM; 288 - } 289 - return 0; 290 - } 291 - 292 - /* 293 - * basic register accessors - read/write long/byte 294 - */ 295 - 296 - static __inline__ unsigned long li_readl(lithium_t *lith, int off) 297 - { 298 - return * (volatile unsigned long *) (lith->page0 + off); 299 - } 300 - 301 - static __inline__ unsigned char li_readb(lithium_t *lith, int off) 302 - { 303 - return * (volatile unsigned char *) (lith->page0 + off); 304 - } 305 - 306 - static __inline__ void li_writel(lithium_t *lith, int off, unsigned long val) 307 - { 308 - * (volatile unsigned long *) (lith->page0 + off) = val; 309 - } 310 - 311 - static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val) 312 - { 313 - * (volatile unsigned char *) (lith->page0 + off) = val; 314 - } 315 - 316 - /*****************************************************************************/ 317 - /* High Level Lithium Access */ 318 - 319 - /* 320 - * Lithium DMA Notes 321 - * 322 - * Lithium has two dedicated DMA channels for audio. They are known 323 - * as comm1 and comm2 (communication areas 1 and 2). Comm1 is for 324 - * input, and comm2 is for output. Each is controlled by three 325 - * registers: BASE (base address), CFG (config) and CCTL 326 - * (config/control). 327 - * 328 - * Each DMA channel points to a physically contiguous ring buffer in 329 - * main memory of up to 8 Kbytes. (This driver always uses 8 Kb.) 330 - * There are three pointers into the ring buffer: read, write, and 331 - * trigger. The pointers are 8 bits each. Each pointer points to 332 - * 32-byte "chunks" of data. The DMA engine moves 32 bytes at a time, 333 - * so there is no finer-granularity control. 334 - * 335 - * In comm1, the hardware updates the write ptr, and software updates 336 - * the read ptr. In comm2, it's the opposite: hardware updates the 337 - * read ptr, and software updates the write ptr. I designate the 338 - * hardware-updated ptr as the hwptr, and the software-updated ptr as 339 - * the swptr. 340 - * 341 - * The trigger ptr and trigger mask are used to trigger interrupts. 342 - * From the Lithium spec, section 5.6.8, revision of 12/15/1998: 343 - * 344 - * Trigger Mask Value 345 - * 346 - * A three bit wide field that represents a power of two mask 347 - * that is used whenever the trigger pointer is compared to its 348 - * respective read or write pointer. A value of zero here 349 - * implies a mask of 0xFF and a value of seven implies a mask 350 - * 0x01. This value can be used to sub-divide the ring buffer 351 - * into pie sections so that interrupts monitor the progress of 352 - * hardware from section to section. 353 - * 354 - * My interpretation of that is, whenever the hw ptr is updated, it is 355 - * compared with the trigger ptr, and the result is masked by the 356 - * trigger mask. (Actually, by the complement of the trigger mask.) 357 - * If the result is zero, an interrupt is triggered. I.e., interrupt 358 - * if ((hwptr & ~mask) == (trptr & ~mask)). The mask is formed from 359 - * the trigger register value as mask = (1 << (8 - tmreg)) - 1. 360 - * 361 - * In yet different words, setting tmreg to 0 causes an interrupt after 362 - * every 256 DMA chunks (8192 bytes) or once per traversal of the 363 - * ring buffer. Setting it to 7 caues an interrupt every 2 DMA chunks 364 - * (64 bytes) or 128 times per traversal of the ring buffer. 365 - */ 366 - 367 - /* Lithium register offsets and bit definitions */ 368 - 369 - #define LI_HOST_CONTROLLER 0x000 370 - # define LI_HC_RESET 0x00008000 371 - # define LI_HC_LINK_ENABLE 0x00004000 372 - # define LI_HC_LINK_FAILURE 0x00000004 373 - # define LI_HC_LINK_CODEC 0x00000002 374 - # define LI_HC_LINK_READY 0x00000001 375 - 376 - #define LI_INTR_STATUS 0x010 377 - #define LI_INTR_MASK 0x014 378 - # define LI_INTR_LINK_ERR 0x00008000 379 - # define LI_INTR_COMM2_TRIG 0x00000008 380 - # define LI_INTR_COMM2_UNDERFLOW 0x00000004 381 - # define LI_INTR_COMM1_TRIG 0x00000002 382 - # define LI_INTR_COMM1_OVERFLOW 0x00000001 383 - 384 - #define LI_CODEC_COMMAND 0x018 385 - # define LI_CC_BUSY 0x00008000 386 - # define LI_CC_DIR 0x00000080 387 - # define LI_CC_DIR_RD LI_CC_DIR 388 - # define LI_CC_DIR_WR (!LI_CC_DIR) 389 - # define LI_CC_ADDR_MASK 0x0000007F 390 - 391 - #define LI_CODEC_DATA 0x01C 392 - 393 - #define LI_COMM1_BASE 0x100 394 - #define LI_COMM1_CTL 0x104 395 - # define LI_CCTL_RESET 0x80000000 396 - # define LI_CCTL_SIZE 0x70000000 397 - # define LI_CCTL_DMA_ENABLE 0x08000000 398 - # define LI_CCTL_TMASK 0x07000000 /* trigger mask */ 399 - # define LI_CCTL_TPTR 0x00FF0000 /* trigger pointer */ 400 - # define LI_CCTL_RPTR 0x0000FF00 401 - # define LI_CCTL_WPTR 0x000000FF 402 - #define LI_COMM1_CFG 0x108 403 - # define LI_CCFG_LOCK 0x00008000 404 - # define LI_CCFG_SLOT 0x00000070 405 - # define LI_CCFG_DIRECTION 0x00000008 406 - # define LI_CCFG_DIR_IN (!LI_CCFG_DIRECTION) 407 - # define LI_CCFG_DIR_OUT LI_CCFG_DIRECTION 408 - # define LI_CCFG_MODE 0x00000004 409 - # define LI_CCFG_MODE_MONO (!LI_CCFG_MODE) 410 - # define LI_CCFG_MODE_STEREO LI_CCFG_MODE 411 - # define LI_CCFG_FORMAT 0x00000003 412 - # define LI_CCFG_FMT_8BIT 0x00000000 413 - # define LI_CCFG_FMT_16BIT 0x00000001 414 - #define LI_COMM2_BASE 0x10C 415 - #define LI_COMM2_CTL 0x110 416 - /* bit definitions are the same as LI_COMM1_CTL */ 417 - #define LI_COMM2_CFG 0x114 418 - /* bit definitions are the same as LI_COMM1_CFG */ 419 - 420 - #define LI_UST_LOW 0x200 /* 64-bit Unadjusted System Time is */ 421 - #define LI_UST_HIGH 0x204 /* microseconds since boot */ 422 - 423 - #define LI_AUDIO1_UST 0x300 /* UST-MSC pairs */ 424 - #define LI_AUDIO1_MSC 0x304 /* MSC (Media Stream Counter) */ 425 - #define LI_AUDIO2_UST 0x308 /* counts samples actually */ 426 - #define LI_AUDIO2_MSC 0x30C /* processed as of time UST */ 427 - 428 - /* 429 - * Lithium's DMA engine operates on chunks of 32 bytes. We call that 430 - * a DMACHUNK. 431 - */ 432 - 433 - #define DMACHUNK_SHIFT 5 434 - #define DMACHUNK_SIZE (1 << DMACHUNK_SHIFT) 435 - #define BYTES_TO_CHUNKS(bytes) ((bytes) >> DMACHUNK_SHIFT) 436 - #define CHUNKS_TO_BYTES(chunks) ((chunks) << DMACHUNK_SHIFT) 437 - 438 - /* 439 - * Two convenient macros to shift bitfields into/out of position. 440 - * 441 - * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)). 442 - * As long as mask is constant, we trust the compiler will change the 443 - * multiply and divide into shifts. 444 - */ 445 - 446 - #define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask)) 447 - #define UNSHIFT_FIELD(val, mask) (((val) & (mask)) / ((mask) & -(mask))) 448 - 449 - /* 450 - * dma_chan_desc is invariant information about a Lithium 451 - * DMA channel. There are two instances, li_comm1 and li_comm2. 452 - * 453 - * Note that the CCTL register fields are write ptr and read ptr, but what 454 - * we care about are which pointer is updated by software and which by 455 - * hardware. 456 - */ 457 - 458 - typedef struct dma_chan_desc { 459 - int basereg; 460 - int cfgreg; 461 - int ctlreg; 462 - int hwptrreg; 463 - int swptrreg; 464 - int ustreg; 465 - int mscreg; 466 - unsigned long swptrmask; 467 - int ad1843_slot; 468 - int direction; /* LI_CCTL_DIR_IN/OUT */ 469 - } dma_chan_desc_t; 470 - 471 - static const dma_chan_desc_t li_comm1 = { 472 - LI_COMM1_BASE, /* base register offset */ 473 - LI_COMM1_CFG, /* config register offset */ 474 - LI_COMM1_CTL, /* control register offset */ 475 - LI_COMM1_CTL + 0, /* hw ptr reg offset (write ptr) */ 476 - LI_COMM1_CTL + 1, /* sw ptr reg offset (read ptr) */ 477 - LI_AUDIO1_UST, /* ust reg offset */ 478 - LI_AUDIO1_MSC, /* msc reg offset */ 479 - LI_CCTL_RPTR, /* sw ptr bitmask in ctlval */ 480 - 2, /* ad1843 serial slot */ 481 - LI_CCFG_DIR_IN /* direction */ 482 - }; 483 - 484 - static const dma_chan_desc_t li_comm2 = { 485 - LI_COMM2_BASE, /* base register offset */ 486 - LI_COMM2_CFG, /* config register offset */ 487 - LI_COMM2_CTL, /* control register offset */ 488 - LI_COMM2_CTL + 1, /* hw ptr reg offset (read ptr) */ 489 - LI_COMM2_CTL + 0, /* sw ptr reg offset (writr ptr) */ 490 - LI_AUDIO2_UST, /* ust reg offset */ 491 - LI_AUDIO2_MSC, /* msc reg offset */ 492 - LI_CCTL_WPTR, /* sw ptr bitmask in ctlval */ 493 - 2, /* ad1843 serial slot */ 494 - LI_CCFG_DIR_OUT /* direction */ 495 - }; 496 - 497 - /* 498 - * dma_chan is variable information about a Lithium DMA channel. 499 - * 500 - * The desc field points to invariant information. 501 - * The lith field points to a lithium_t which is passed 502 - * to li_read* and li_write* to access the registers. 503 - * The *val fields shadow the lithium registers' contents. 504 - */ 505 - 506 - typedef struct dma_chan { 507 - const dma_chan_desc_t *desc; 508 - lithium_t *lith; 509 - unsigned long baseval; 510 - unsigned long cfgval; 511 - unsigned long ctlval; 512 - } dma_chan_t; 513 - 514 - /* 515 - * ustmsc is a UST/MSC pair (Unadjusted System Time/Media Stream Counter). 516 - * UST is time in microseconds since the system booted, and MSC is a 517 - * counter that increments with every audio sample. 518 - */ 519 - 520 - typedef struct ustmsc { 521 - unsigned long long ust; 522 - unsigned long msc; 523 - } ustmsc_t; 524 - 525 - /* 526 - * li_ad1843_wait waits until lithium says the AD1843 register 527 - * exchange is not busy. Returns 0 on success, -EBUSY on timeout. 528 - * 529 - * Locking: must be called with lithium_lock held. 530 - */ 531 - 532 - static int li_ad1843_wait(lithium_t *lith) 533 - { 534 - unsigned long later = jiffies + 2; 535 - while (li_readl(lith, LI_CODEC_COMMAND) & LI_CC_BUSY) 536 - if (time_after_eq(jiffies, later)) 537 - return -EBUSY; 538 - return 0; 539 - } 540 - 541 - /* 542 - * li_read_ad1843_reg returns the current contents of a 16 bit AD1843 register. 543 - * 544 - * Returns unsigned register value on success, -errno on failure. 545 - */ 546 - 547 - static int li_read_ad1843_reg(lithium_t *lith, int reg) 548 - { 549 - int val; 550 - 551 - ASSERT(!in_interrupt()); 552 - spin_lock(&lith->lock); 553 - { 554 - val = li_ad1843_wait(lith); 555 - if (val == 0) { 556 - li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_RD | reg); 557 - val = li_ad1843_wait(lith); 558 - } 559 - if (val == 0) 560 - val = li_readl(lith, LI_CODEC_DATA); 561 - } 562 - spin_unlock(&lith->lock); 563 - 564 - DBGXV("li_read_ad1843_reg(lith=0x%p, reg=%d) returns 0x%04x\n", 565 - lith, reg, val); 566 - 567 - return val; 568 - } 569 - 570 - /* 571 - * li_write_ad1843_reg writes the specified value to a 16 bit AD1843 register. 572 - */ 573 - 574 - static void li_write_ad1843_reg(lithium_t *lith, int reg, int newval) 575 - { 576 - spin_lock(&lith->lock); 577 - { 578 - if (li_ad1843_wait(lith) == 0) { 579 - li_writel(lith, LI_CODEC_DATA, newval); 580 - li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_WR | reg); 581 - } 582 - } 583 - spin_unlock(&lith->lock); 584 - } 585 - 586 - /* 587 - * li_setup_dma calculates all the register settings for DMA in a particular 588 - * mode. It takes too many arguments. 589 - */ 590 - 591 - static void li_setup_dma(dma_chan_t *chan, 592 - const dma_chan_desc_t *desc, 593 - lithium_t *lith, 594 - unsigned long buffer_paddr, 595 - int bufshift, 596 - int fragshift, 597 - int channels, 598 - int sampsize) 599 - { 600 - unsigned long mode, format; 601 - unsigned long size, tmask; 602 - 603 - DBGEV("(chan=0x%p, desc=0x%p, lith=0x%p, buffer_paddr=0x%lx, " 604 - "bufshift=%d, fragshift=%d, channels=%d, sampsize=%d)\n", 605 - chan, desc, lith, buffer_paddr, 606 - bufshift, fragshift, channels, sampsize); 607 - 608 - /* Reset the channel first. */ 609 - 610 - li_writel(lith, desc->ctlreg, LI_CCTL_RESET); 611 - 612 - ASSERT(channels == 1 || channels == 2); 613 - if (channels == 2) 614 - mode = LI_CCFG_MODE_STEREO; 615 - else 616 - mode = LI_CCFG_MODE_MONO; 617 - ASSERT(sampsize == 1 || sampsize == 2); 618 - if (sampsize == 2) 619 - format = LI_CCFG_FMT_16BIT; 620 - else 621 - format = LI_CCFG_FMT_8BIT; 622 - chan->desc = desc; 623 - chan->lith = lith; 624 - 625 - /* 626 - * Lithium DMA address register takes a 40-bit physical 627 - * address, right-shifted by 8 so it fits in 32 bits. Bit 37 628 - * must be set -- it enables cache coherence. 629 - */ 630 - 631 - ASSERT(!(buffer_paddr & 0xFF)); 632 - chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8); 633 - 634 - chan->cfgval = ((chan->cfgval & ~LI_CCFG_LOCK) | 635 - SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) | 636 - desc->direction | 637 - mode | 638 - format); 639 - 640 - size = bufshift - 6; 641 - tmask = 13 - fragshift; /* See Lithium DMA Notes above. */ 642 - ASSERT(size >= 2 && size <= 7); 643 - ASSERT(tmask >= 1 && tmask <= 7); 644 - chan->ctlval = ((chan->ctlval & ~LI_CCTL_RESET) | 645 - SHIFT_FIELD(size, LI_CCTL_SIZE) | 646 - (chan->ctlval & ~LI_CCTL_DMA_ENABLE) | 647 - SHIFT_FIELD(tmask, LI_CCTL_TMASK) | 648 - SHIFT_FIELD(0, LI_CCTL_TPTR)); 649 - 650 - DBGPV("basereg 0x%x = 0x%lx\n", desc->basereg, chan->baseval); 651 - DBGPV("cfgreg 0x%x = 0x%lx\n", desc->cfgreg, chan->cfgval); 652 - DBGPV("ctlreg 0x%x = 0x%lx\n", desc->ctlreg, chan->ctlval); 653 - 654 - li_writel(lith, desc->basereg, chan->baseval); 655 - li_writel(lith, desc->cfgreg, chan->cfgval); 656 - li_writel(lith, desc->ctlreg, chan->ctlval); 657 - 658 - DBGRV(); 659 - } 660 - 661 - static void li_shutdown_dma(dma_chan_t *chan) 662 - { 663 - lithium_t *lith = chan->lith; 664 - void * lith1 = lith->page1; 665 - 666 - DBGEV("(chan=0x%p)\n", chan); 667 - 668 - chan->ctlval &= ~LI_CCTL_DMA_ENABLE; 669 - DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval); 670 - li_writel(lith, chan->desc->ctlreg, chan->ctlval); 671 - 672 - /* 673 - * Offset 0x500 on Lithium page 1 is an undocumented, 674 - * unsupported register that holds the zero sample value. 675 - * Lithium is supposed to output zero samples when DMA is 676 - * inactive, and repeat the last sample when DMA underflows. 677 - * But it has a bug, where, after underflow occurs, the zero 678 - * sample is not reset. 679 - * 680 - * I expect this to break in a future rev of Lithium. 681 - */ 682 - 683 - if (lith1 && chan->desc->direction == LI_CCFG_DIR_OUT) 684 - * (volatile unsigned long *) (lith1 + 0x500) = 0; 685 - } 686 - 687 - /* 688 - * li_activate_dma always starts dma at the beginning of the buffer. 689 - * 690 - * N.B., these may be called from interrupt. 691 - */ 692 - 693 - static __inline__ void li_activate_dma(dma_chan_t *chan) 694 - { 695 - chan->ctlval |= LI_CCTL_DMA_ENABLE; 696 - DBGPV("ctlval = 0x%lx\n", chan->ctlval); 697 - li_writel(chan->lith, chan->desc->ctlreg, chan->ctlval); 698 - } 699 - 700 - static void li_deactivate_dma(dma_chan_t *chan) 701 - { 702 - lithium_t *lith = chan->lith; 703 - void * lith2 = lith->page2; 704 - 705 - chan->ctlval &= ~(LI_CCTL_DMA_ENABLE | LI_CCTL_RPTR | LI_CCTL_WPTR); 706 - DBGPV("ctlval = 0x%lx\n", chan->ctlval); 707 - DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval); 708 - li_writel(lith, chan->desc->ctlreg, chan->ctlval); 709 - 710 - /* 711 - * Offsets 0x98 and 0x9C on Lithium page 2 are undocumented, 712 - * unsupported registers that are internal copies of the DMA 713 - * read and write pointers. Because of a Lithium bug, these 714 - * registers aren't zeroed correctly when DMA is shut off. So 715 - * we whack them directly. 716 - * 717 - * I expect this to break in a future rev of Lithium. 718 - */ 719 - 720 - if (lith2 && chan->desc->direction == LI_CCFG_DIR_OUT) { 721 - * (volatile unsigned long *) (lith2 + 0x98) = 0; 722 - * (volatile unsigned long *) (lith2 + 0x9C) = 0; 723 - } 724 - } 725 - 726 - /* 727 - * read/write the ring buffer pointers. These routines' arguments and results 728 - * are byte offsets from the beginning of the ring buffer. 729 - */ 730 - 731 - static __inline__ int li_read_swptr(dma_chan_t *chan) 732 - { 733 - const unsigned long mask = chan->desc->swptrmask; 734 - 735 - return CHUNKS_TO_BYTES(UNSHIFT_FIELD(chan->ctlval, mask)); 736 - } 737 - 738 - static __inline__ int li_read_hwptr(dma_chan_t *chan) 739 - { 740 - return CHUNKS_TO_BYTES(li_readb(chan->lith, chan->desc->hwptrreg)); 741 - } 742 - 743 - static __inline__ void li_write_swptr(dma_chan_t *chan, int val) 744 - { 745 - const unsigned long mask = chan->desc->swptrmask; 746 - 747 - ASSERT(!(val & ~CHUNKS_TO_BYTES(0xFF))); 748 - val = BYTES_TO_CHUNKS(val); 749 - chan->ctlval = (chan->ctlval & ~mask) | SHIFT_FIELD(val, mask); 750 - li_writeb(chan->lith, chan->desc->swptrreg, val); 751 - } 752 - 753 - /* li_read_USTMSC() returns a UST/MSC pair for the given channel. */ 754 - 755 - static void li_read_USTMSC(dma_chan_t *chan, ustmsc_t *ustmsc) 756 - { 757 - lithium_t *lith = chan->lith; 758 - const dma_chan_desc_t *desc = chan->desc; 759 - unsigned long now_low, now_high0, now_high1, chan_ust; 760 - 761 - spin_lock(&lith->lock); 762 - { 763 - /* 764 - * retry until we do all five reads without the 765 - * high word changing. (High word increments 766 - * every 2^32 microseconds, i.e., not often) 767 - */ 768 - do { 769 - now_high0 = li_readl(lith, LI_UST_HIGH); 770 - now_low = li_readl(lith, LI_UST_LOW); 771 - 772 - /* 773 - * Lithium guarantees these two reads will be 774 - * atomic -- ust will not increment after msc 775 - * is read. 776 - */ 777 - 778 - ustmsc->msc = li_readl(lith, desc->mscreg); 779 - chan_ust = li_readl(lith, desc->ustreg); 780 - 781 - now_high1 = li_readl(lith, LI_UST_HIGH); 782 - } while (now_high0 != now_high1); 783 - } 784 - spin_unlock(&lith->lock); 785 - ustmsc->ust = ((unsigned long long) now_high0 << 32 | chan_ust); 786 - } 787 - 788 - static void li_enable_interrupts(lithium_t *lith, unsigned int mask) 789 - { 790 - DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask); 791 - 792 - /* clear any already-pending interrupts. */ 793 - 794 - li_writel(lith, LI_INTR_STATUS, mask); 795 - 796 - /* enable the interrupts. */ 797 - 798 - mask |= li_readl(lith, LI_INTR_MASK); 799 - li_writel(lith, LI_INTR_MASK, mask); 800 - } 801 - 802 - static void li_disable_interrupts(lithium_t *lith, unsigned int mask) 803 - { 804 - unsigned int keepmask; 805 - 806 - DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask); 807 - 808 - /* disable the interrupts */ 809 - 810 - keepmask = li_readl(lith, LI_INTR_MASK) & ~mask; 811 - li_writel(lith, LI_INTR_MASK, keepmask); 812 - 813 - /* clear any pending interrupts. */ 814 - 815 - li_writel(lith, LI_INTR_STATUS, mask); 816 - } 817 - 818 - /* Get the interrupt status and clear all pending interrupts. */ 819 - 820 - static unsigned int li_get_clear_intr_status(lithium_t *lith) 821 - { 822 - unsigned int status; 823 - 824 - status = li_readl(lith, LI_INTR_STATUS); 825 - li_writel(lith, LI_INTR_STATUS, ~0); 826 - return status & li_readl(lith, LI_INTR_MASK); 827 - } 828 - 829 - static int li_init(lithium_t *lith) 830 - { 831 - /* 1. System power supplies stabilize. */ 832 - 833 - /* 2. Assert the ~RESET signal. */ 834 - 835 - li_writel(lith, LI_HOST_CONTROLLER, LI_HC_RESET); 836 - udelay(1); 837 - 838 - /* 3. Deassert the ~RESET signal and enter a wait period to allow 839 - the AD1843 internal clocks and the external crystal oscillator 840 - to stabilize. */ 841 - 842 - li_writel(lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE); 843 - udelay(1); 844 - 845 - return 0; 846 - } 847 - 848 - /*****************************************************************************/ 849 - /* AD1843 access */ 850 - 851 - /* 852 - * AD1843 bitfield definitions. All are named as in the AD1843 data 853 - * sheet, with ad1843_ prepended and individual bit numbers removed. 854 - * 855 - * E.g., bits LSS0 through LSS2 become ad1843_LSS. 856 - * 857 - * Only the bitfields we need are defined. 858 - */ 859 - 860 - typedef struct ad1843_bitfield { 861 - char reg; 862 - char lo_bit; 863 - char nbits; 864 - } ad1843_bitfield_t; 865 - 866 - static const ad1843_bitfield_t 867 - ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */ 868 - ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */ 869 - ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */ 870 - ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */ 871 - ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */ 872 - ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */ 873 - ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */ 874 - ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */ 875 - ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */ 876 - ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */ 877 - ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */ 878 - ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */ 879 - ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */ 880 - ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */ 881 - ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */ 882 - ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */ 883 - ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */ 884 - ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */ 885 - ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */ 886 - ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */ 887 - ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */ 888 - ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */ 889 - ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */ 890 - ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */ 891 - ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */ 892 - ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */ 893 - ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */ 894 - ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */ 895 - ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */ 896 - ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */ 897 - ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */ 898 - ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */ 899 - ad1843_C2C = { 20, 0, 16 }, /* Clock 1 Sample Rate Select */ 900 - ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */ 901 - ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */ 902 - ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */ 903 - ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */ 904 - ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */ 905 - ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */ 906 - ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */ 907 - ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */ 908 - ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */ 909 - ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */ 910 - ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */ 911 - ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */ 912 - ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */ 913 - ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */ 914 - ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */ 915 - ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */ 916 - ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */ 917 - ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */ 918 - 919 - /* 920 - * The various registers of the AD1843 use three different formats for 921 - * specifying gain. The ad1843_gain structure parameterizes the 922 - * formats. 923 - */ 924 - 925 - typedef struct ad1843_gain { 926 - 927 - int negative; /* nonzero if gain is negative. */ 928 - const ad1843_bitfield_t *lfield; 929 - const ad1843_bitfield_t *rfield; 930 - 931 - } ad1843_gain_t; 932 - 933 - static const ad1843_gain_t ad1843_gain_RECLEV 934 - = { 0, &ad1843_LIG, &ad1843_RIG }; 935 - static const ad1843_gain_t ad1843_gain_LINE 936 - = { 1, &ad1843_LX1M, &ad1843_RX1M }; 937 - static const ad1843_gain_t ad1843_gain_CD 938 - = { 1, &ad1843_LX2M, &ad1843_RX2M }; 939 - static const ad1843_gain_t ad1843_gain_MIC 940 - = { 1, &ad1843_LMCM, &ad1843_RMCM }; 941 - static const ad1843_gain_t ad1843_gain_PCM 942 - = { 1, &ad1843_LDA1G, &ad1843_RDA1G }; 943 - 944 - /* read the current value of an AD1843 bitfield. */ 945 - 946 - static int ad1843_read_bits(lithium_t *lith, const ad1843_bitfield_t *field) 947 - { 948 - int w = li_read_ad1843_reg(lith, field->reg); 949 - int val = w >> field->lo_bit & ((1 << field->nbits) - 1); 950 - 951 - DBGXV("ad1843_read_bits(lith=0x%p, field->{%d %d %d}) returns 0x%x\n", 952 - lith, field->reg, field->lo_bit, field->nbits, val); 953 - 954 - return val; 955 - } 956 - 957 - /* 958 - * write a new value to an AD1843 bitfield and return the old value. 959 - */ 960 - 961 - static int ad1843_write_bits(lithium_t *lith, 962 - const ad1843_bitfield_t *field, 963 - int newval) 964 - { 965 - int w = li_read_ad1843_reg(lith, field->reg); 966 - int mask = ((1 << field->nbits) - 1) << field->lo_bit; 967 - int oldval = (w & mask) >> field->lo_bit; 968 - int newbits = (newval << field->lo_bit) & mask; 969 - w = (w & ~mask) | newbits; 970 - (void) li_write_ad1843_reg(lith, field->reg, w); 971 - 972 - DBGXV("ad1843_write_bits(lith=0x%p, field->{%d %d %d}, val=0x%x) " 973 - "returns 0x%x\n", 974 - lith, field->reg, field->lo_bit, field->nbits, newval, 975 - oldval); 976 - 977 - return oldval; 978 - } 979 - 980 - /* 981 - * ad1843_read_multi reads multiple bitfields from the same AD1843 982 - * register. It uses a single read cycle to do it. (Reading the 983 - * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20 984 - * microseconds.) 985 - * 986 - * Called ike this. 987 - * 988 - * ad1843_read_multi(lith, nfields, 989 - * &ad1843_FIELD1, &val1, 990 - * &ad1843_FIELD2, &val2, ...); 991 - */ 992 - 993 - static void ad1843_read_multi(lithium_t *lith, int argcount, ...) 994 - { 995 - va_list ap; 996 - const ad1843_bitfield_t *fp; 997 - int w = 0, mask, *value, reg = -1; 998 - 999 - va_start(ap, argcount); 1000 - while (--argcount >= 0) { 1001 - fp = va_arg(ap, const ad1843_bitfield_t *); 1002 - value = va_arg(ap, int *); 1003 - if (reg == -1) { 1004 - reg = fp->reg; 1005 - w = li_read_ad1843_reg(lith, reg); 1006 - } 1007 - ASSERT(reg == fp->reg); 1008 - mask = (1 << fp->nbits) - 1; 1009 - *value = w >> fp->lo_bit & mask; 1010 - } 1011 - va_end(ap); 1012 - } 1013 - 1014 - /* 1015 - * ad1843_write_multi stores multiple bitfields into the same AD1843 1016 - * register. It uses one read and one write cycle to do it. 1017 - * 1018 - * Called like this. 1019 - * 1020 - * ad1843_write_multi(lith, nfields, 1021 - * &ad1843_FIELD1, val1, 1022 - * &ad1843_FIELF2, val2, ...); 1023 - */ 1024 - 1025 - static void ad1843_write_multi(lithium_t *lith, int argcount, ...) 1026 - { 1027 - va_list ap; 1028 - int reg; 1029 - const ad1843_bitfield_t *fp; 1030 - int value; 1031 - int w, m, mask, bits; 1032 - 1033 - mask = 0; 1034 - bits = 0; 1035 - reg = -1; 1036 - 1037 - va_start(ap, argcount); 1038 - while (--argcount >= 0) { 1039 - fp = va_arg(ap, const ad1843_bitfield_t *); 1040 - value = va_arg(ap, int); 1041 - if (reg == -1) 1042 - reg = fp->reg; 1043 - ASSERT(fp->reg == reg); 1044 - m = ((1 << fp->nbits) - 1) << fp->lo_bit; 1045 - mask |= m; 1046 - bits |= (value << fp->lo_bit) & m; 1047 - } 1048 - va_end(ap); 1049 - ASSERT(!(bits & ~mask)); 1050 - if (~mask & 0xFFFF) 1051 - w = li_read_ad1843_reg(lith, reg); 1052 - else 1053 - w = 0; 1054 - w = (w & ~mask) | bits; 1055 - (void) li_write_ad1843_reg(lith, reg, w); 1056 - } 1057 - 1058 - /* 1059 - * ad1843_get_gain reads the specified register and extracts the gain value 1060 - * using the supplied gain type. It returns the gain in OSS format. 1061 - */ 1062 - 1063 - static int ad1843_get_gain(lithium_t *lith, const ad1843_gain_t *gp) 1064 - { 1065 - int lg, rg; 1066 - unsigned short mask = (1 << gp->lfield->nbits) - 1; 1067 - 1068 - ad1843_read_multi(lith, 2, gp->lfield, &lg, gp->rfield, &rg); 1069 - if (gp->negative) { 1070 - lg = mask - lg; 1071 - rg = mask - rg; 1072 - } 1073 - lg = (lg * 100 + (mask >> 1)) / mask; 1074 - rg = (rg * 100 + (mask >> 1)) / mask; 1075 - return lg << 0 | rg << 8; 1076 - } 1077 - 1078 - /* 1079 - * Set an audio channel's gain. Converts from OSS format to AD1843's 1080 - * format. 1081 - * 1082 - * Returns the new gain, which may be lower than the old gain. 1083 - */ 1084 - 1085 - static int ad1843_set_gain(lithium_t *lith, 1086 - const ad1843_gain_t *gp, 1087 - int newval) 1088 - { 1089 - unsigned short mask = (1 << gp->lfield->nbits) - 1; 1090 - 1091 - int lg = newval >> 0 & 0xFF; 1092 - int rg = newval >> 8; 1093 - if (lg < 0 || lg > 100 || rg < 0 || rg > 100) 1094 - return -EINVAL; 1095 - lg = (lg * mask + (mask >> 1)) / 100; 1096 - rg = (rg * mask + (mask >> 1)) / 100; 1097 - if (gp->negative) { 1098 - lg = mask - lg; 1099 - rg = mask - rg; 1100 - } 1101 - ad1843_write_multi(lith, 2, gp->lfield, lg, gp->rfield, rg); 1102 - return ad1843_get_gain(lith, gp); 1103 - } 1104 - 1105 - /* Returns the current recording source, in OSS format. */ 1106 - 1107 - static int ad1843_get_recsrc(lithium_t *lith) 1108 - { 1109 - int ls = ad1843_read_bits(lith, &ad1843_LSS); 1110 - 1111 - switch (ls) { 1112 - case 1: 1113 - return SOUND_MASK_MIC; 1114 - case 2: 1115 - return SOUND_MASK_LINE; 1116 - case 3: 1117 - return SOUND_MASK_CD; 1118 - case 6: 1119 - return SOUND_MASK_PCM; 1120 - default: 1121 - ASSERT(0); 1122 - return -1; 1123 - } 1124 - } 1125 - 1126 - /* 1127 - * Enable/disable digital resample mode in the AD1843. 1128 - * 1129 - * The AD1843 requires that ADL, ADR, DA1 and DA2 be powered down 1130 - * while switching modes. So we save DA1's state (DA2's state is not 1131 - * interesting), power them down, switch into/out of resample mode, 1132 - * power them up, and restore state. 1133 - * 1134 - * This will cause audible glitches if D/A or A/D is going on, so the 1135 - * driver disallows that (in mixer_write_ioctl()). 1136 - * 1137 - * The open question is, is this worth doing? I'm leaving it in, 1138 - * because it's written, but... 1139 - */ 1140 - 1141 - static void ad1843_set_resample_mode(lithium_t *lith, int onoff) 1142 - { 1143 - /* Save DA1 mute and gain (addr 9 is DA1 analog gain/attenuation) */ 1144 - int save_da1 = li_read_ad1843_reg(lith, 9); 1145 - 1146 - /* Power down A/D and D/A. */ 1147 - ad1843_write_multi(lith, 4, 1148 - &ad1843_DA1EN, 0, 1149 - &ad1843_DA2EN, 0, 1150 - &ad1843_ADLEN, 0, 1151 - &ad1843_ADREN, 0); 1152 - 1153 - /* Switch mode */ 1154 - ASSERT(onoff == 0 || onoff == 1); 1155 - ad1843_write_bits(lith, &ad1843_DRSFLT, onoff); 1156 - 1157 - /* Power up A/D and D/A. */ 1158 - ad1843_write_multi(lith, 3, 1159 - &ad1843_DA1EN, 1, 1160 - &ad1843_ADLEN, 1, 1161 - &ad1843_ADREN, 1); 1162 - 1163 - /* Restore DA1 mute and gain. */ 1164 - li_write_ad1843_reg(lith, 9, save_da1); 1165 - } 1166 - 1167 - /* 1168 - * Set recording source. Arg newsrc specifies an OSS channel mask. 1169 - * 1170 - * The complication is that when we switch into/out of loopback mode 1171 - * (i.e., src = SOUND_MASK_PCM), we change the AD1843 into/out of 1172 - * digital resampling mode. 1173 - * 1174 - * Returns newsrc on success, -errno on failure. 1175 - */ 1176 - 1177 - static int ad1843_set_recsrc(lithium_t *lith, int newsrc) 1178 - { 1179 - int bits; 1180 - int oldbits; 1181 - 1182 - switch (newsrc) { 1183 - case SOUND_MASK_PCM: 1184 - bits = 6; 1185 - break; 1186 - 1187 - case SOUND_MASK_MIC: 1188 - bits = 1; 1189 - break; 1190 - 1191 - case SOUND_MASK_LINE: 1192 - bits = 2; 1193 - break; 1194 - 1195 - case SOUND_MASK_CD: 1196 - bits = 3; 1197 - break; 1198 - 1199 - default: 1200 - return -EINVAL; 1201 - } 1202 - oldbits = ad1843_read_bits(lith, &ad1843_LSS); 1203 - if (newsrc == SOUND_MASK_PCM && oldbits != 6) { 1204 - DBGP("enabling digital resample mode\n"); 1205 - ad1843_set_resample_mode(lith, 1); 1206 - ad1843_write_multi(lith, 2, 1207 - &ad1843_DAADL, 2, 1208 - &ad1843_DAADR, 2); 1209 - } else if (newsrc != SOUND_MASK_PCM && oldbits == 6) { 1210 - DBGP("disabling digital resample mode\n"); 1211 - ad1843_set_resample_mode(lith, 0); 1212 - ad1843_write_multi(lith, 2, 1213 - &ad1843_DAADL, 0, 1214 - &ad1843_DAADR, 0); 1215 - } 1216 - ad1843_write_multi(lith, 2, &ad1843_LSS, bits, &ad1843_RSS, bits); 1217 - return newsrc; 1218 - } 1219 - 1220 - /* 1221 - * Return current output sources, in OSS format. 1222 - */ 1223 - 1224 - static int ad1843_get_outsrc(lithium_t *lith) 1225 - { 1226 - int pcm, line, mic, cd; 1227 - 1228 - pcm = ad1843_read_bits(lith, &ad1843_LDA1GM) ? 0 : SOUND_MASK_PCM; 1229 - line = ad1843_read_bits(lith, &ad1843_LX1MM) ? 0 : SOUND_MASK_LINE; 1230 - cd = ad1843_read_bits(lith, &ad1843_LX2MM) ? 0 : SOUND_MASK_CD; 1231 - mic = ad1843_read_bits(lith, &ad1843_LMCMM) ? 0 : SOUND_MASK_MIC; 1232 - 1233 - return pcm | line | cd | mic; 1234 - } 1235 - 1236 - /* 1237 - * Set output sources. Arg is a mask of active sources in OSS format. 1238 - * 1239 - * Returns source mask on success, -errno on failure. 1240 - */ 1241 - 1242 - static int ad1843_set_outsrc(lithium_t *lith, int mask) 1243 - { 1244 - int pcm, line, mic, cd; 1245 - 1246 - if (mask & ~(SOUND_MASK_PCM | SOUND_MASK_LINE | 1247 - SOUND_MASK_CD | SOUND_MASK_MIC)) 1248 - return -EINVAL; 1249 - pcm = (mask & SOUND_MASK_PCM) ? 0 : 1; 1250 - line = (mask & SOUND_MASK_LINE) ? 0 : 1; 1251 - mic = (mask & SOUND_MASK_MIC) ? 0 : 1; 1252 - cd = (mask & SOUND_MASK_CD) ? 0 : 1; 1253 - 1254 - ad1843_write_multi(lith, 2, &ad1843_LDA1GM, pcm, &ad1843_RDA1GM, pcm); 1255 - ad1843_write_multi(lith, 2, &ad1843_LX1MM, line, &ad1843_RX1MM, line); 1256 - ad1843_write_multi(lith, 2, &ad1843_LX2MM, cd, &ad1843_RX2MM, cd); 1257 - ad1843_write_multi(lith, 2, &ad1843_LMCMM, mic, &ad1843_RMCMM, mic); 1258 - 1259 - return mask; 1260 - } 1261 - 1262 - /* Setup ad1843 for D/A conversion. */ 1263 - 1264 - static void ad1843_setup_dac(lithium_t *lith, 1265 - int framerate, 1266 - int fmt, 1267 - int channels) 1268 - { 1269 - int ad_fmt = 0, ad_mode = 0; 1270 - 1271 - DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n", 1272 - lith, framerate, fmt, channels); 1273 - 1274 - switch (fmt) { 1275 - case AFMT_S8: ad_fmt = 1; break; 1276 - case AFMT_U8: ad_fmt = 1; break; 1277 - case AFMT_S16_LE: ad_fmt = 1; break; 1278 - case AFMT_MU_LAW: ad_fmt = 2; break; 1279 - case AFMT_A_LAW: ad_fmt = 3; break; 1280 - default: ASSERT(0); 1281 - } 1282 - 1283 - switch (channels) { 1284 - case 2: ad_mode = 0; break; 1285 - case 1: ad_mode = 1; break; 1286 - default: ASSERT(0); 1287 - } 1288 - 1289 - DBGPV("ad_mode = %d, ad_fmt = %d\n", ad_mode, ad_fmt); 1290 - ASSERT(framerate >= 4000 && framerate <= 49000); 1291 - ad1843_write_bits(lith, &ad1843_C1C, framerate); 1292 - ad1843_write_multi(lith, 2, 1293 - &ad1843_DA1SM, ad_mode, &ad1843_DA1F, ad_fmt); 1294 - } 1295 - 1296 - static void ad1843_shutdown_dac(lithium_t *lith) 1297 - { 1298 - ad1843_write_bits(lith, &ad1843_DA1F, 1); 1299 - } 1300 - 1301 - static void ad1843_setup_adc(lithium_t *lith, int framerate, int fmt, int channels) 1302 - { 1303 - int da_fmt = 0; 1304 - 1305 - DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n", 1306 - lith, framerate, fmt, channels); 1307 - 1308 - switch (fmt) { 1309 - case AFMT_S8: da_fmt = 1; break; 1310 - case AFMT_U8: da_fmt = 1; break; 1311 - case AFMT_S16_LE: da_fmt = 1; break; 1312 - case AFMT_MU_LAW: da_fmt = 2; break; 1313 - case AFMT_A_LAW: da_fmt = 3; break; 1314 - default: ASSERT(0); 1315 - } 1316 - 1317 - DBGPV("da_fmt = %d\n", da_fmt); 1318 - ASSERT(framerate >= 4000 && framerate <= 49000); 1319 - ad1843_write_bits(lith, &ad1843_C2C, framerate); 1320 - ad1843_write_multi(lith, 2, 1321 - &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt); 1322 - } 1323 - 1324 - static void ad1843_shutdown_adc(lithium_t *lith) 1325 - { 1326 - /* nothing to do */ 1327 - } 1328 - 1329 - /* 1330 - * Fully initialize the ad1843. As described in the AD1843 data 1331 - * sheet, section "START-UP SEQUENCE". The numbered comments are 1332 - * subsection headings from the data sheet. See the data sheet, pages 1333 - * 52-54, for more info. 1334 - * 1335 - * return 0 on success, -errno on failure. */ 1336 - 1337 - static int __init ad1843_init(lithium_t *lith) 1338 - { 1339 - unsigned long later; 1340 - int err; 1341 - 1342 - err = li_init(lith); 1343 - if (err) 1344 - return err; 1345 - 1346 - if (ad1843_read_bits(lith, &ad1843_INIT) != 0) { 1347 - printk(KERN_ERR "vwsnd sound: AD1843 won't initialize\n"); 1348 - return -EIO; 1349 - } 1350 - 1351 - ad1843_write_bits(lith, &ad1843_SCF, 1); 1352 - 1353 - /* 4. Put the conversion resources into standby. */ 1354 - 1355 - ad1843_write_bits(lith, &ad1843_PDNI, 0); 1356 - later = jiffies + HZ / 2; /* roughly half a second */ 1357 - DBGDO(shut_up++); 1358 - while (ad1843_read_bits(lith, &ad1843_PDNO)) { 1359 - if (time_after(jiffies, later)) { 1360 - printk(KERN_ERR 1361 - "vwsnd audio: AD1843 won't power up\n"); 1362 - return -EIO; 1363 - } 1364 - schedule(); 1365 - } 1366 - DBGDO(shut_up--); 1367 - 1368 - /* 5. Power up the clock generators and enable clock output pins. */ 1369 - 1370 - ad1843_write_multi(lith, 2, &ad1843_C1EN, 1, &ad1843_C2EN, 1); 1371 - 1372 - /* 6. Configure conversion resources while they are in standby. */ 1373 - 1374 - /* DAC1 uses clock 1 as source, ADC uses clock 2. Always. */ 1375 - 1376 - ad1843_write_multi(lith, 3, 1377 - &ad1843_DA1C, 1, 1378 - &ad1843_ADLC, 2, 1379 - &ad1843_ADRC, 2); 1380 - 1381 - /* 7. Enable conversion resources. */ 1382 - 1383 - ad1843_write_bits(lith, &ad1843_ADTLK, 1); 1384 - ad1843_write_multi(lith, 5, 1385 - &ad1843_ANAEN, 1, 1386 - &ad1843_AAMEN, 1, 1387 - &ad1843_DA1EN, 1, 1388 - &ad1843_ADLEN, 1, 1389 - &ad1843_ADREN, 1); 1390 - 1391 - /* 8. Configure conversion resources while they are enabled. */ 1392 - 1393 - ad1843_write_bits(lith, &ad1843_DA1C, 1); 1394 - 1395 - /* Unmute all channels. */ 1396 - 1397 - ad1843_set_outsrc(lith, 1398 - (SOUND_MASK_PCM | SOUND_MASK_LINE | 1399 - SOUND_MASK_MIC | SOUND_MASK_CD)); 1400 - ad1843_write_multi(lith, 2, &ad1843_LDA1AM, 0, &ad1843_RDA1AM, 0); 1401 - 1402 - /* Set default recording source to Line In and set 1403 - * mic gain to +20 dB. 1404 - */ 1405 - 1406 - ad1843_set_recsrc(lith, SOUND_MASK_LINE); 1407 - ad1843_write_multi(lith, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1); 1408 - 1409 - /* Set Speaker Out level to +/- 4V and unmute it. */ 1410 - 1411 - ad1843_write_multi(lith, 2, &ad1843_HPOS, 1, &ad1843_HPOM, 0); 1412 - 1413 - return 0; 1414 - } 1415 - 1416 - /*****************************************************************************/ 1417 - /* PCM I/O */ 1418 - 1419 - #define READ_INTR_MASK (LI_INTR_COMM1_TRIG | LI_INTR_COMM1_OVERFLOW) 1420 - #define WRITE_INTR_MASK (LI_INTR_COMM2_TRIG | LI_INTR_COMM2_UNDERFLOW) 1421 - 1422 - typedef enum vwsnd_port_swstate { /* software state */ 1423 - SW_OFF, 1424 - SW_INITIAL, 1425 - SW_RUN, 1426 - SW_DRAIN, 1427 - } vwsnd_port_swstate_t; 1428 - 1429 - typedef enum vwsnd_port_hwstate { /* hardware state */ 1430 - HW_STOPPED, 1431 - HW_RUNNING, 1432 - } vwsnd_port_hwstate_t; 1433 - 1434 - /* 1435 - * These flags are read by ISR, but only written at baseline. 1436 - */ 1437 - 1438 - typedef enum vwsnd_port_flags { 1439 - DISABLED = 1 << 0, 1440 - ERFLOWN = 1 << 1, /* overflown or underflown */ 1441 - HW_BUSY = 1 << 2, 1442 - } vwsnd_port_flags_t; 1443 - 1444 - /* 1445 - * vwsnd_port is the per-port data structure. Each device has two 1446 - * ports, one for input and one for output. 1447 - * 1448 - * Locking: 1449 - * 1450 - * port->lock protects: hwstate, flags, swb_[iu]_avail. 1451 - * 1452 - * devc->io_mutex protects: swstate, sw_*, swb_[iu]_idx. 1453 - * 1454 - * everything else is only written by open/release or 1455 - * pcm_{setup,shutdown}(), which are serialized by a 1456 - * combination of devc->open_mutex and devc->io_mutex. 1457 - */ 1458 - 1459 - typedef struct vwsnd_port { 1460 - 1461 - spinlock_t lock; 1462 - wait_queue_head_t queue; 1463 - vwsnd_port_swstate_t swstate; 1464 - vwsnd_port_hwstate_t hwstate; 1465 - vwsnd_port_flags_t flags; 1466 - 1467 - int sw_channels; 1468 - int sw_samplefmt; 1469 - int sw_framerate; 1470 - int sample_size; 1471 - int frame_size; 1472 - unsigned int zero_word; /* zero for the sample format */ 1473 - 1474 - int sw_fragshift; 1475 - int sw_fragcount; 1476 - int sw_subdivshift; 1477 - 1478 - unsigned int hw_fragshift; 1479 - unsigned int hw_fragsize; 1480 - unsigned int hw_fragcount; 1481 - 1482 - int hwbuf_size; 1483 - unsigned long hwbuf_paddr; 1484 - unsigned long hwbuf_vaddr; 1485 - void * hwbuf; /* hwbuf == hwbuf_vaddr */ 1486 - int hwbuf_max; /* max bytes to preload */ 1487 - 1488 - void * swbuf; 1489 - unsigned int swbuf_size; /* size in bytes */ 1490 - unsigned int swb_u_idx; /* index of next user byte */ 1491 - unsigned int swb_i_idx; /* index of next intr byte */ 1492 - unsigned int swb_u_avail; /* # bytes avail to user */ 1493 - unsigned int swb_i_avail; /* # bytes avail to intr */ 1494 - 1495 - dma_chan_t chan; 1496 - 1497 - /* Accounting */ 1498 - 1499 - int byte_count; 1500 - int frag_count; 1501 - int MSC_offset; 1502 - 1503 - } vwsnd_port_t; 1504 - 1505 - /* vwsnd_dev is the per-device data structure. */ 1506 - 1507 - typedef struct vwsnd_dev { 1508 - struct vwsnd_dev *next_dev; 1509 - int audio_minor; /* minor number of audio device */ 1510 - int mixer_minor; /* minor number of mixer device */ 1511 - 1512 - struct mutex open_mutex; 1513 - struct mutex io_mutex; 1514 - struct mutex mix_mutex; 1515 - fmode_t open_mode; 1516 - wait_queue_head_t open_wait; 1517 - 1518 - lithium_t lith; 1519 - 1520 - vwsnd_port_t rport; 1521 - vwsnd_port_t wport; 1522 - } vwsnd_dev_t; 1523 - 1524 - static vwsnd_dev_t *vwsnd_dev_list; /* linked list of all devices */ 1525 - 1526 - static atomic_t vwsnd_use_count = ATOMIC_INIT(0); 1527 - 1528 - # define INC_USE_COUNT (atomic_inc(&vwsnd_use_count)) 1529 - # define DEC_USE_COUNT (atomic_dec(&vwsnd_use_count)) 1530 - # define IN_USE (atomic_read(&vwsnd_use_count) != 0) 1531 - 1532 - /* 1533 - * Lithium can only DMA multiples of 32 bytes. Its DMA buffer may 1534 - * be up to 8 Kb. This driver always uses 8 Kb. 1535 - * 1536 - * Memory bug workaround -- I'm not sure what's going on here, but 1537 - * somehow pcm_copy_out() was triggering segv's going on to the next 1538 - * page of the hw buffer. So, I make the hw buffer one size bigger 1539 - * than we actually use. That way, the following page is allocated 1540 - * and mapped, and no error. I suspect that something is broken 1541 - * in Cobalt, but haven't really investigated. HBO is the actual 1542 - * size of the buffer, and HWBUF_ORDER is what we allocate. 1543 - */ 1544 - 1545 - #define HWBUF_SHIFT 13 1546 - #define HWBUF_SIZE (1 << HWBUF_SHIFT) 1547 - # define HBO (HWBUF_SHIFT > PAGE_SHIFT ? HWBUF_SHIFT - PAGE_SHIFT : 0) 1548 - # define HWBUF_ORDER (HBO + 1) /* next size bigger */ 1549 - #define MIN_SPEED 4000 1550 - #define MAX_SPEED 49000 1551 - 1552 - #define MIN_FRAGSHIFT (DMACHUNK_SHIFT + 1) 1553 - #define MAX_FRAGSHIFT (PAGE_SHIFT) 1554 - #define MIN_FRAGSIZE (1 << MIN_FRAGSHIFT) 1555 - #define MAX_FRAGSIZE (1 << MAX_FRAGSHIFT) 1556 - #define MIN_FRAGCOUNT(fragsize) 3 1557 - #define MAX_FRAGCOUNT(fragsize) (32 * PAGE_SIZE / (fragsize)) 1558 - #define DEFAULT_FRAGSHIFT 12 1559 - #define DEFAULT_FRAGCOUNT 16 1560 - #define DEFAULT_SUBDIVSHIFT 0 1561 - 1562 - /* 1563 - * The software buffer (swbuf) is a ring buffer shared between user 1564 - * level and interrupt level. Each level owns some of the bytes in 1565 - * the buffer, and may give bytes away by calling swb_inc_{u,i}(). 1566 - * User level calls _u for user, and interrupt level calls _i for 1567 - * interrupt. 1568 - * 1569 - * port->swb_{u,i}_avail is the number of bytes available to that level. 1570 - * 1571 - * port->swb_{u,i}_idx is the index of the first available byte in the 1572 - * buffer. 1573 - * 1574 - * Each level calls swb_inc_{u,i}() to atomically increment its index, 1575 - * recalculate the number of bytes available for both sides, and 1576 - * return the number of bytes available. Since each side can only 1577 - * give away bytes, the other side can only increase the number of 1578 - * bytes available to this side. Each side updates its own index 1579 - * variable, swb_{u,i}_idx, so no lock is needed to read it. 1580 - * 1581 - * To query the number of bytes available, call swb_inc_{u,i} with an 1582 - * increment of zero. 1583 - */ 1584 - 1585 - static __inline__ unsigned int __swb_inc_u(vwsnd_port_t *port, int inc) 1586 - { 1587 - if (inc) { 1588 - port->swb_u_idx += inc; 1589 - port->swb_u_idx %= port->swbuf_size; 1590 - port->swb_u_avail -= inc; 1591 - port->swb_i_avail += inc; 1592 - } 1593 - return port->swb_u_avail; 1594 - } 1595 - 1596 - static __inline__ unsigned int swb_inc_u(vwsnd_port_t *port, int inc) 1597 - { 1598 - unsigned long flags; 1599 - unsigned int ret; 1600 - 1601 - spin_lock_irqsave(&port->lock, flags); 1602 - { 1603 - ret = __swb_inc_u(port, inc); 1604 - } 1605 - spin_unlock_irqrestore(&port->lock, flags); 1606 - return ret; 1607 - } 1608 - 1609 - static __inline__ unsigned int __swb_inc_i(vwsnd_port_t *port, int inc) 1610 - { 1611 - if (inc) { 1612 - port->swb_i_idx += inc; 1613 - port->swb_i_idx %= port->swbuf_size; 1614 - port->swb_i_avail -= inc; 1615 - port->swb_u_avail += inc; 1616 - } 1617 - return port->swb_i_avail; 1618 - } 1619 - 1620 - static __inline__ unsigned int swb_inc_i(vwsnd_port_t *port, int inc) 1621 - { 1622 - unsigned long flags; 1623 - unsigned int ret; 1624 - 1625 - spin_lock_irqsave(&port->lock, flags); 1626 - { 1627 - ret = __swb_inc_i(port, inc); 1628 - } 1629 - spin_unlock_irqrestore(&port->lock, flags); 1630 - return ret; 1631 - } 1632 - 1633 - /* 1634 - * pcm_setup - this routine initializes all port state after 1635 - * mode-setting ioctls have been done, but before the first I/O is 1636 - * done. 1637 - * 1638 - * Locking: called with devc->io_mutex held. 1639 - * 1640 - * Returns 0 on success, -errno on failure. 1641 - */ 1642 - 1643 - static int pcm_setup(vwsnd_dev_t *devc, 1644 - vwsnd_port_t *rport, 1645 - vwsnd_port_t *wport) 1646 - { 1647 - vwsnd_port_t *aport = rport ? rport : wport; 1648 - int sample_size; 1649 - unsigned int zero_word; 1650 - 1651 - DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport); 1652 - 1653 - ASSERT(aport != NULL); 1654 - if (aport->swbuf != NULL) 1655 - return 0; 1656 - switch (aport->sw_samplefmt) { 1657 - case AFMT_MU_LAW: 1658 - sample_size = 1; 1659 - zero_word = 0xFFFFFFFF ^ 0x80808080; 1660 - break; 1661 - 1662 - case AFMT_A_LAW: 1663 - sample_size = 1; 1664 - zero_word = 0xD5D5D5D5 ^ 0x80808080; 1665 - break; 1666 - 1667 - case AFMT_U8: 1668 - sample_size = 1; 1669 - zero_word = 0x80808080; 1670 - break; 1671 - 1672 - case AFMT_S8: 1673 - sample_size = 1; 1674 - zero_word = 0x00000000; 1675 - break; 1676 - 1677 - case AFMT_S16_LE: 1678 - sample_size = 2; 1679 - zero_word = 0x00000000; 1680 - break; 1681 - 1682 - default: 1683 - sample_size = 0; /* prevent compiler warning */ 1684 - zero_word = 0; 1685 - ASSERT(0); 1686 - } 1687 - aport->sample_size = sample_size; 1688 - aport->zero_word = zero_word; 1689 - aport->frame_size = aport->sw_channels * aport->sample_size; 1690 - aport->hw_fragshift = aport->sw_fragshift - aport->sw_subdivshift; 1691 - aport->hw_fragsize = 1 << aport->hw_fragshift; 1692 - aport->hw_fragcount = aport->sw_fragcount << aport->sw_subdivshift; 1693 - ASSERT(aport->hw_fragsize >= MIN_FRAGSIZE); 1694 - ASSERT(aport->hw_fragsize <= MAX_FRAGSIZE); 1695 - ASSERT(aport->hw_fragcount >= MIN_FRAGCOUNT(aport->hw_fragsize)); 1696 - ASSERT(aport->hw_fragcount <= MAX_FRAGCOUNT(aport->hw_fragsize)); 1697 - if (rport) { 1698 - int hwfrags, swfrags; 1699 - rport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE; 1700 - hwfrags = rport->hwbuf_max >> aport->hw_fragshift; 1701 - swfrags = aport->hw_fragcount - hwfrags; 1702 - if (swfrags < 2) 1703 - swfrags = 2; 1704 - rport->swbuf_size = swfrags * aport->hw_fragsize; 1705 - DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags); 1706 - DBGPV("read hwbuf_max = %d, swbuf_size = %d\n", 1707 - rport->hwbuf_max, rport->swbuf_size); 1708 - } 1709 - if (wport) { 1710 - int hwfrags, swfrags; 1711 - int total_bytes = aport->hw_fragcount * aport->hw_fragsize; 1712 - wport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE; 1713 - if (wport->hwbuf_max > total_bytes) 1714 - wport->hwbuf_max = total_bytes; 1715 - hwfrags = wport->hwbuf_max >> aport->hw_fragshift; 1716 - DBGPV("hwfrags = %d\n", hwfrags); 1717 - swfrags = aport->hw_fragcount - hwfrags; 1718 - if (swfrags < 2) 1719 - swfrags = 2; 1720 - wport->swbuf_size = swfrags * aport->hw_fragsize; 1721 - DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags); 1722 - DBGPV("write hwbuf_max = %d, swbuf_size = %d\n", 1723 - wport->hwbuf_max, wport->swbuf_size); 1724 - } 1725 - 1726 - aport->swb_u_idx = 0; 1727 - aport->swb_i_idx = 0; 1728 - aport->byte_count = 0; 1729 - 1730 - /* 1731 - * Is this a Cobalt bug? We need to make this buffer extend 1732 - * one page further than we actually use -- somehow memcpy 1733 - * causes an exceptoin otherwise. I suspect there's a bug in 1734 - * Cobalt (or somewhere) where it's generating a fault on a 1735 - * speculative load or something. Obviously, I haven't taken 1736 - * the time to track it down. 1737 - */ 1738 - 1739 - aport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE); 1740 - if (!aport->swbuf) 1741 - return -ENOMEM; 1742 - if (rport && wport) { 1743 - ASSERT(aport == rport); 1744 - ASSERT(wport->swbuf == NULL); 1745 - /* One extra page - see comment above. */ 1746 - wport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE); 1747 - if (!wport->swbuf) { 1748 - vfree(aport->swbuf); 1749 - aport->swbuf = NULL; 1750 - return -ENOMEM; 1751 - } 1752 - wport->sample_size = rport->sample_size; 1753 - wport->zero_word = rport->zero_word; 1754 - wport->frame_size = rport->frame_size; 1755 - wport->hw_fragshift = rport->hw_fragshift; 1756 - wport->hw_fragsize = rport->hw_fragsize; 1757 - wport->hw_fragcount = rport->hw_fragcount; 1758 - wport->swbuf_size = rport->swbuf_size; 1759 - wport->hwbuf_max = rport->hwbuf_max; 1760 - wport->swb_u_idx = rport->swb_u_idx; 1761 - wport->swb_i_idx = rport->swb_i_idx; 1762 - wport->byte_count = rport->byte_count; 1763 - } 1764 - if (rport) { 1765 - rport->swb_u_avail = 0; 1766 - rport->swb_i_avail = rport->swbuf_size; 1767 - rport->swstate = SW_RUN; 1768 - li_setup_dma(&rport->chan, 1769 - &li_comm1, 1770 - &devc->lith, 1771 - rport->hwbuf_paddr, 1772 - HWBUF_SHIFT, 1773 - rport->hw_fragshift, 1774 - rport->sw_channels, 1775 - rport->sample_size); 1776 - ad1843_setup_adc(&devc->lith, 1777 - rport->sw_framerate, 1778 - rport->sw_samplefmt, 1779 - rport->sw_channels); 1780 - li_enable_interrupts(&devc->lith, READ_INTR_MASK); 1781 - if (!(rport->flags & DISABLED)) { 1782 - ustmsc_t ustmsc; 1783 - rport->hwstate = HW_RUNNING; 1784 - li_activate_dma(&rport->chan); 1785 - li_read_USTMSC(&rport->chan, &ustmsc); 1786 - rport->MSC_offset = ustmsc.msc; 1787 - } 1788 - } 1789 - if (wport) { 1790 - if (wport->hwbuf_max > wport->swbuf_size) 1791 - wport->hwbuf_max = wport->swbuf_size; 1792 - wport->flags &= ~ERFLOWN; 1793 - wport->swb_u_avail = wport->swbuf_size; 1794 - wport->swb_i_avail = 0; 1795 - wport->swstate = SW_RUN; 1796 - li_setup_dma(&wport->chan, 1797 - &li_comm2, 1798 - &devc->lith, 1799 - wport->hwbuf_paddr, 1800 - HWBUF_SHIFT, 1801 - wport->hw_fragshift, 1802 - wport->sw_channels, 1803 - wport->sample_size); 1804 - ad1843_setup_dac(&devc->lith, 1805 - wport->sw_framerate, 1806 - wport->sw_samplefmt, 1807 - wport->sw_channels); 1808 - li_enable_interrupts(&devc->lith, WRITE_INTR_MASK); 1809 - } 1810 - DBGRV(); 1811 - return 0; 1812 - } 1813 - 1814 - /* 1815 - * pcm_shutdown_port - shut down one port (direction) for PCM I/O. 1816 - * Only called from pcm_shutdown. 1817 - */ 1818 - 1819 - static void pcm_shutdown_port(vwsnd_dev_t *devc, 1820 - vwsnd_port_t *aport, 1821 - unsigned int mask) 1822 - { 1823 - unsigned long flags; 1824 - vwsnd_port_hwstate_t hwstate; 1825 - DECLARE_WAITQUEUE(wait, current); 1826 - 1827 - aport->swstate = SW_INITIAL; 1828 - add_wait_queue(&aport->queue, &wait); 1829 - while (1) { 1830 - set_current_state(TASK_UNINTERRUPTIBLE); 1831 - spin_lock_irqsave(&aport->lock, flags); 1832 - { 1833 - hwstate = aport->hwstate; 1834 - } 1835 - spin_unlock_irqrestore(&aport->lock, flags); 1836 - if (hwstate == HW_STOPPED) 1837 - break; 1838 - schedule(); 1839 - } 1840 - current->state = TASK_RUNNING; 1841 - remove_wait_queue(&aport->queue, &wait); 1842 - li_disable_interrupts(&devc->lith, mask); 1843 - if (aport == &devc->rport) 1844 - ad1843_shutdown_adc(&devc->lith); 1845 - else /* aport == &devc->wport) */ 1846 - ad1843_shutdown_dac(&devc->lith); 1847 - li_shutdown_dma(&aport->chan); 1848 - vfree(aport->swbuf); 1849 - aport->swbuf = NULL; 1850 - aport->byte_count = 0; 1851 - } 1852 - 1853 - /* 1854 - * pcm_shutdown undoes what pcm_setup did. 1855 - * Also sets the ports' swstate to newstate. 1856 - */ 1857 - 1858 - static void pcm_shutdown(vwsnd_dev_t *devc, 1859 - vwsnd_port_t *rport, 1860 - vwsnd_port_t *wport) 1861 - { 1862 - DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport); 1863 - 1864 - if (rport && rport->swbuf) { 1865 - DBGPV("shutting down rport\n"); 1866 - pcm_shutdown_port(devc, rport, READ_INTR_MASK); 1867 - } 1868 - if (wport && wport->swbuf) { 1869 - DBGPV("shutting down wport\n"); 1870 - pcm_shutdown_port(devc, wport, WRITE_INTR_MASK); 1871 - } 1872 - DBGRV(); 1873 - } 1874 - 1875 - static void pcm_copy_in(vwsnd_port_t *rport, int swidx, int hwidx, int nb) 1876 - { 1877 - char *src = rport->hwbuf + hwidx; 1878 - char *dst = rport->swbuf + swidx; 1879 - int fmt = rport->sw_samplefmt; 1880 - 1881 - DBGPV("swidx = %d, hwidx = %d\n", swidx, hwidx); 1882 - ASSERT(rport->hwbuf != NULL); 1883 - ASSERT(rport->swbuf != NULL); 1884 - ASSERT(nb > 0 && (nb % 32) == 0); 1885 - ASSERT(swidx % 32 == 0 && hwidx % 32 == 0); 1886 - ASSERT(swidx >= 0 && swidx + nb <= rport->swbuf_size); 1887 - ASSERT(hwidx >= 0 && hwidx + nb <= rport->hwbuf_size); 1888 - 1889 - if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) { 1890 - 1891 - /* See Sample Format Notes above. */ 1892 - 1893 - char *end = src + nb; 1894 - while (src < end) 1895 - *dst++ = *src++ ^ 0x80; 1896 - } else 1897 - memcpy(dst, src, nb); 1898 - } 1899 - 1900 - static void pcm_copy_out(vwsnd_port_t *wport, int swidx, int hwidx, int nb) 1901 - { 1902 - char *src = wport->swbuf + swidx; 1903 - char *dst = wport->hwbuf + hwidx; 1904 - int fmt = wport->sw_samplefmt; 1905 - 1906 - ASSERT(nb > 0 && (nb % 32) == 0); 1907 - ASSERT(wport->hwbuf != NULL); 1908 - ASSERT(wport->swbuf != NULL); 1909 - ASSERT(swidx % 32 == 0 && hwidx % 32 == 0); 1910 - ASSERT(swidx >= 0 && swidx + nb <= wport->swbuf_size); 1911 - ASSERT(hwidx >= 0 && hwidx + nb <= wport->hwbuf_size); 1912 - if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) { 1913 - 1914 - /* See Sample Format Notes above. */ 1915 - 1916 - char *end = src + nb; 1917 - while (src < end) 1918 - *dst++ = *src++ ^ 0x80; 1919 - } else 1920 - memcpy(dst, src, nb); 1921 - } 1922 - 1923 - /* 1924 - * pcm_output() is called both from baselevel and from interrupt level. 1925 - * This is where audio frames are copied into the hardware-accessible 1926 - * ring buffer. 1927 - * 1928 - * Locking note: The part of this routine that figures out what to do 1929 - * holds wport->lock. The longer part releases wport->lock, but sets 1930 - * wport->flags & HW_BUSY. Afterward, it reacquires wport->lock, and 1931 - * checks for more work to do. 1932 - * 1933 - * If another thread calls pcm_output() while HW_BUSY is set, it 1934 - * returns immediately, knowing that the thread that set HW_BUSY will 1935 - * look for more work to do before returning. 1936 - * 1937 - * This has the advantage that port->lock is held for several short 1938 - * periods instead of one long period. Also, when pcm_output is 1939 - * called from base level, it reenables interrupts. 1940 - */ 1941 - 1942 - static void pcm_output(vwsnd_dev_t *devc, int erflown, int nb) 1943 - { 1944 - vwsnd_port_t *wport = &devc->wport; 1945 - const int hwmax = wport->hwbuf_max; 1946 - const int hwsize = wport->hwbuf_size; 1947 - const int swsize = wport->swbuf_size; 1948 - const int fragsize = wport->hw_fragsize; 1949 - unsigned long iflags; 1950 - 1951 - DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb); 1952 - spin_lock_irqsave(&wport->lock, iflags); 1953 - if (erflown) 1954 - wport->flags |= ERFLOWN; 1955 - (void) __swb_inc_u(wport, nb); 1956 - if (wport->flags & HW_BUSY) { 1957 - spin_unlock_irqrestore(&wport->lock, iflags); 1958 - DBGPV("returning: HW BUSY\n"); 1959 - return; 1960 - } 1961 - if (wport->flags & DISABLED) { 1962 - spin_unlock_irqrestore(&wport->lock, iflags); 1963 - DBGPV("returning: DISABLED\n"); 1964 - return; 1965 - } 1966 - wport->flags |= HW_BUSY; 1967 - while (1) { 1968 - int swptr, hwptr, hw_avail, sw_avail, swidx; 1969 - vwsnd_port_hwstate_t hwstate = wport->hwstate; 1970 - vwsnd_port_swstate_t swstate = wport->swstate; 1971 - int hw_unavail; 1972 - ustmsc_t ustmsc; 1973 - 1974 - hwptr = li_read_hwptr(&wport->chan); 1975 - swptr = li_read_swptr(&wport->chan); 1976 - hw_unavail = (swptr - hwptr + hwsize) % hwsize; 1977 - hw_avail = (hwmax - hw_unavail) & -fragsize; 1978 - sw_avail = wport->swb_i_avail & -fragsize; 1979 - if (sw_avail && swstate == SW_RUN) { 1980 - if (wport->flags & ERFLOWN) { 1981 - wport->flags &= ~ERFLOWN; 1982 - } 1983 - } else if (swstate == SW_INITIAL || 1984 - swstate == SW_OFF || 1985 - (swstate == SW_DRAIN && 1986 - !sw_avail && 1987 - (wport->flags & ERFLOWN))) { 1988 - DBGP("stopping. hwstate = %d\n", hwstate); 1989 - if (hwstate != HW_STOPPED) { 1990 - li_deactivate_dma(&wport->chan); 1991 - wport->hwstate = HW_STOPPED; 1992 - } 1993 - wake_up(&wport->queue); 1994 - break; 1995 - } 1996 - if (!sw_avail || !hw_avail) 1997 - break; 1998 - spin_unlock_irqrestore(&wport->lock, iflags); 1999 - 2000 - /* 2001 - * We gave up the port lock, but we have the HW_BUSY flag. 2002 - * Proceed without accessing any nonlocal state. 2003 - * Do not exit the loop -- must check for more work. 2004 - */ 2005 - 2006 - swidx = wport->swb_i_idx; 2007 - nb = hw_avail; 2008 - if (nb > sw_avail) 2009 - nb = sw_avail; 2010 - if (nb > hwsize - swptr) 2011 - nb = hwsize - swptr; /* don't overflow hwbuf */ 2012 - if (nb > swsize - swidx) 2013 - nb = swsize - swidx; /* don't overflow swbuf */ 2014 - ASSERT(nb > 0); 2015 - if (nb % fragsize) { 2016 - DBGP("nb = %d, fragsize = %d\n", nb, fragsize); 2017 - DBGP("hw_avail = %d\n", hw_avail); 2018 - DBGP("sw_avail = %d\n", sw_avail); 2019 - DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr); 2020 - DBGP("swsize = %d, swidx = %d\n", swsize, swidx); 2021 - } 2022 - ASSERT(!(nb % fragsize)); 2023 - DBGPV("copying swb[%d..%d] to hwb[%d..%d]\n", 2024 - swidx, swidx + nb, swptr, swptr + nb); 2025 - pcm_copy_out(wport, swidx, swptr, nb); 2026 - li_write_swptr(&wport->chan, (swptr + nb) % hwsize); 2027 - spin_lock_irqsave(&wport->lock, iflags); 2028 - if (hwstate == HW_STOPPED) { 2029 - DBGPV("starting\n"); 2030 - li_activate_dma(&wport->chan); 2031 - wport->hwstate = HW_RUNNING; 2032 - li_read_USTMSC(&wport->chan, &ustmsc); 2033 - ASSERT(wport->byte_count % wport->frame_size == 0); 2034 - wport->MSC_offset = ustmsc.msc - wport->byte_count / wport->frame_size; 2035 - } 2036 - __swb_inc_i(wport, nb); 2037 - wport->byte_count += nb; 2038 - wport->frag_count += nb / fragsize; 2039 - ASSERT(nb % fragsize == 0); 2040 - wake_up(&wport->queue); 2041 - } 2042 - wport->flags &= ~HW_BUSY; 2043 - spin_unlock_irqrestore(&wport->lock, iflags); 2044 - DBGRV(); 2045 - } 2046 - 2047 - /* 2048 - * pcm_input() is called both from baselevel and from interrupt level. 2049 - * This is where audio frames are copied out of the hardware-accessible 2050 - * ring buffer. 2051 - * 2052 - * Locking note: The part of this routine that figures out what to do 2053 - * holds rport->lock. The longer part releases rport->lock, but sets 2054 - * rport->flags & HW_BUSY. Afterward, it reacquires rport->lock, and 2055 - * checks for more work to do. 2056 - * 2057 - * If another thread calls pcm_input() while HW_BUSY is set, it 2058 - * returns immediately, knowing that the thread that set HW_BUSY will 2059 - * look for more work to do before returning. 2060 - * 2061 - * This has the advantage that port->lock is held for several short 2062 - * periods instead of one long period. Also, when pcm_input is 2063 - * called from base level, it reenables interrupts. 2064 - */ 2065 - 2066 - static void pcm_input(vwsnd_dev_t *devc, int erflown, int nb) 2067 - { 2068 - vwsnd_port_t *rport = &devc->rport; 2069 - const int hwmax = rport->hwbuf_max; 2070 - const int hwsize = rport->hwbuf_size; 2071 - const int swsize = rport->swbuf_size; 2072 - const int fragsize = rport->hw_fragsize; 2073 - unsigned long iflags; 2074 - 2075 - DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb); 2076 - 2077 - spin_lock_irqsave(&rport->lock, iflags); 2078 - if (erflown) 2079 - rport->flags |= ERFLOWN; 2080 - (void) __swb_inc_u(rport, nb); 2081 - if (rport->flags & HW_BUSY || !rport->swbuf) { 2082 - spin_unlock_irqrestore(&rport->lock, iflags); 2083 - DBGPV("returning: HW BUSY or !swbuf\n"); 2084 - return; 2085 - } 2086 - if (rport->flags & DISABLED) { 2087 - spin_unlock_irqrestore(&rport->lock, iflags); 2088 - DBGPV("returning: DISABLED\n"); 2089 - return; 2090 - } 2091 - rport->flags |= HW_BUSY; 2092 - while (1) { 2093 - int swptr, hwptr, hw_avail, sw_avail, swidx; 2094 - vwsnd_port_hwstate_t hwstate = rport->hwstate; 2095 - vwsnd_port_swstate_t swstate = rport->swstate; 2096 - 2097 - hwptr = li_read_hwptr(&rport->chan); 2098 - swptr = li_read_swptr(&rport->chan); 2099 - hw_avail = (hwptr - swptr + hwsize) % hwsize & -fragsize; 2100 - if (hw_avail > hwmax) 2101 - hw_avail = hwmax; 2102 - sw_avail = rport->swb_i_avail & -fragsize; 2103 - if (swstate != SW_RUN) { 2104 - DBGP("stopping. hwstate = %d\n", hwstate); 2105 - if (hwstate != HW_STOPPED) { 2106 - li_deactivate_dma(&rport->chan); 2107 - rport->hwstate = HW_STOPPED; 2108 - } 2109 - wake_up(&rport->queue); 2110 - break; 2111 - } 2112 - if (!sw_avail || !hw_avail) 2113 - break; 2114 - spin_unlock_irqrestore(&rport->lock, iflags); 2115 - 2116 - /* 2117 - * We gave up the port lock, but we have the HW_BUSY flag. 2118 - * Proceed without accessing any nonlocal state. 2119 - * Do not exit the loop -- must check for more work. 2120 - */ 2121 - 2122 - swidx = rport->swb_i_idx; 2123 - nb = hw_avail; 2124 - if (nb > sw_avail) 2125 - nb = sw_avail; 2126 - if (nb > hwsize - swptr) 2127 - nb = hwsize - swptr; /* don't overflow hwbuf */ 2128 - if (nb > swsize - swidx) 2129 - nb = swsize - swidx; /* don't overflow swbuf */ 2130 - ASSERT(nb > 0); 2131 - if (nb % fragsize) { 2132 - DBGP("nb = %d, fragsize = %d\n", nb, fragsize); 2133 - DBGP("hw_avail = %d\n", hw_avail); 2134 - DBGP("sw_avail = %d\n", sw_avail); 2135 - DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr); 2136 - DBGP("swsize = %d, swidx = %d\n", swsize, swidx); 2137 - } 2138 - ASSERT(!(nb % fragsize)); 2139 - DBGPV("copying hwb[%d..%d] to swb[%d..%d]\n", 2140 - swptr, swptr + nb, swidx, swidx + nb); 2141 - pcm_copy_in(rport, swidx, swptr, nb); 2142 - li_write_swptr(&rport->chan, (swptr + nb) % hwsize); 2143 - spin_lock_irqsave(&rport->lock, iflags); 2144 - __swb_inc_i(rport, nb); 2145 - rport->byte_count += nb; 2146 - rport->frag_count += nb / fragsize; 2147 - ASSERT(nb % fragsize == 0); 2148 - wake_up(&rport->queue); 2149 - } 2150 - rport->flags &= ~HW_BUSY; 2151 - spin_unlock_irqrestore(&rport->lock, iflags); 2152 - DBGRV(); 2153 - } 2154 - 2155 - /* 2156 - * pcm_flush_frag() writes zero samples to fill the current fragment, 2157 - * then flushes it to the hardware. 2158 - * 2159 - * It is only meaningful to flush output, not input. 2160 - */ 2161 - 2162 - static void pcm_flush_frag(vwsnd_dev_t *devc) 2163 - { 2164 - vwsnd_port_t *wport = &devc->wport; 2165 - 2166 - DBGPV("swstate = %d\n", wport->swstate); 2167 - if (wport->swstate == SW_RUN) { 2168 - int idx = wport->swb_u_idx; 2169 - int end = (idx + wport->hw_fragsize - 1) 2170 - >> wport->hw_fragshift 2171 - << wport->hw_fragshift; 2172 - int nb = end - idx; 2173 - DBGPV("clearing %d bytes\n", nb); 2174 - if (nb) 2175 - memset(wport->swbuf + idx, 2176 - (char) wport->zero_word, 2177 - nb); 2178 - wport->swstate = SW_DRAIN; 2179 - pcm_output(devc, 0, nb); 2180 - } 2181 - DBGRV(); 2182 - } 2183 - 2184 - /* 2185 - * Wait for output to drain. This sleeps uninterruptibly because 2186 - * there is nothing intelligent we can do if interrupted. This 2187 - * means the process will be delayed in responding to the signal. 2188 - */ 2189 - 2190 - static void pcm_write_sync(vwsnd_dev_t *devc) 2191 - { 2192 - vwsnd_port_t *wport = &devc->wport; 2193 - DECLARE_WAITQUEUE(wait, current); 2194 - unsigned long flags; 2195 - vwsnd_port_hwstate_t hwstate; 2196 - 2197 - DBGEV("(devc=0x%p)\n", devc); 2198 - add_wait_queue(&wport->queue, &wait); 2199 - while (1) { 2200 - set_current_state(TASK_UNINTERRUPTIBLE); 2201 - spin_lock_irqsave(&wport->lock, flags); 2202 - { 2203 - hwstate = wport->hwstate; 2204 - } 2205 - spin_unlock_irqrestore(&wport->lock, flags); 2206 - if (hwstate == HW_STOPPED) 2207 - break; 2208 - schedule(); 2209 - } 2210 - current->state = TASK_RUNNING; 2211 - remove_wait_queue(&wport->queue, &wait); 2212 - DBGPV("swstate = %d, hwstate = %d\n", wport->swstate, wport->hwstate); 2213 - DBGRV(); 2214 - } 2215 - 2216 - /*****************************************************************************/ 2217 - /* audio driver */ 2218 - 2219 - /* 2220 - * seek on an audio device always fails. 2221 - */ 2222 - 2223 - static void vwsnd_audio_read_intr(vwsnd_dev_t *devc, unsigned int status) 2224 - { 2225 - int overflown = status & LI_INTR_COMM1_OVERFLOW; 2226 - 2227 - if (status & READ_INTR_MASK) 2228 - pcm_input(devc, overflown, 0); 2229 - } 2230 - 2231 - static void vwsnd_audio_write_intr(vwsnd_dev_t *devc, unsigned int status) 2232 - { 2233 - int underflown = status & LI_INTR_COMM2_UNDERFLOW; 2234 - 2235 - if (status & WRITE_INTR_MASK) 2236 - pcm_output(devc, underflown, 0); 2237 - } 2238 - 2239 - static irqreturn_t vwsnd_audio_intr(int irq, void *dev_id) 2240 - { 2241 - vwsnd_dev_t *devc = dev_id; 2242 - unsigned int status; 2243 - 2244 - DBGEV("(irq=%d, dev_id=0x%p)\n", irq, dev_id); 2245 - 2246 - status = li_get_clear_intr_status(&devc->lith); 2247 - vwsnd_audio_read_intr(devc, status); 2248 - vwsnd_audio_write_intr(devc, status); 2249 - return IRQ_HANDLED; 2250 - } 2251 - 2252 - static ssize_t vwsnd_audio_do_read(struct file *file, 2253 - char *buffer, 2254 - size_t count, 2255 - loff_t *ppos) 2256 - { 2257 - vwsnd_dev_t *devc = file->private_data; 2258 - vwsnd_port_t *rport = ((file->f_mode & FMODE_READ) ? 2259 - &devc->rport : NULL); 2260 - int ret, nb; 2261 - 2262 - DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n", 2263 - file, buffer, count, ppos); 2264 - 2265 - if (!rport) 2266 - return -EINVAL; 2267 - 2268 - if (rport->swbuf == NULL) { 2269 - vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ? 2270 - &devc->wport : NULL; 2271 - ret = pcm_setup(devc, rport, wport); 2272 - if (ret < 0) 2273 - return ret; 2274 - } 2275 - 2276 - if (!access_ok(VERIFY_READ, buffer, count)) 2277 - return -EFAULT; 2278 - ret = 0; 2279 - while (count) { 2280 - DECLARE_WAITQUEUE(wait, current); 2281 - add_wait_queue(&rport->queue, &wait); 2282 - while ((nb = swb_inc_u(rport, 0)) == 0) { 2283 - DBGPV("blocking\n"); 2284 - set_current_state(TASK_INTERRUPTIBLE); 2285 - if (rport->flags & DISABLED || 2286 - file->f_flags & O_NONBLOCK) { 2287 - current->state = TASK_RUNNING; 2288 - remove_wait_queue(&rport->queue, &wait); 2289 - return ret ? ret : -EAGAIN; 2290 - } 2291 - schedule(); 2292 - if (signal_pending(current)) { 2293 - current->state = TASK_RUNNING; 2294 - remove_wait_queue(&rport->queue, &wait); 2295 - return ret ? ret : -ERESTARTSYS; 2296 - } 2297 - } 2298 - current->state = TASK_RUNNING; 2299 - remove_wait_queue(&rport->queue, &wait); 2300 - pcm_input(devc, 0, 0); 2301 - /* nb bytes are available in userbuf. */ 2302 - if (nb > count) 2303 - nb = count; 2304 - DBGPV("nb = %d\n", nb); 2305 - if (copy_to_user(buffer, rport->swbuf + rport->swb_u_idx, nb)) 2306 - return -EFAULT; 2307 - (void) swb_inc_u(rport, nb); 2308 - buffer += nb; 2309 - count -= nb; 2310 - ret += nb; 2311 - } 2312 - DBGPV("returning %d\n", ret); 2313 - return ret; 2314 - } 2315 - 2316 - static ssize_t vwsnd_audio_read(struct file *file, 2317 - char *buffer, 2318 - size_t count, 2319 - loff_t *ppos) 2320 - { 2321 - vwsnd_dev_t *devc = file->private_data; 2322 - ssize_t ret; 2323 - 2324 - mutex_lock(&devc->io_mutex); 2325 - ret = vwsnd_audio_do_read(file, buffer, count, ppos); 2326 - mutex_unlock(&devc->io_mutex); 2327 - return ret; 2328 - } 2329 - 2330 - static ssize_t vwsnd_audio_do_write(struct file *file, 2331 - const char *buffer, 2332 - size_t count, 2333 - loff_t *ppos) 2334 - { 2335 - vwsnd_dev_t *devc = file->private_data; 2336 - vwsnd_port_t *wport = ((file->f_mode & FMODE_WRITE) ? 2337 - &devc->wport : NULL); 2338 - int ret, nb; 2339 - 2340 - DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n", 2341 - file, buffer, count, ppos); 2342 - 2343 - if (!wport) 2344 - return -EINVAL; 2345 - 2346 - if (wport->swbuf == NULL) { 2347 - vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ? 2348 - &devc->rport : NULL; 2349 - ret = pcm_setup(devc, rport, wport); 2350 - if (ret < 0) 2351 - return ret; 2352 - } 2353 - if (!access_ok(VERIFY_WRITE, buffer, count)) 2354 - return -EFAULT; 2355 - ret = 0; 2356 - while (count) { 2357 - DECLARE_WAITQUEUE(wait, current); 2358 - add_wait_queue(&wport->queue, &wait); 2359 - while ((nb = swb_inc_u(wport, 0)) == 0) { 2360 - set_current_state(TASK_INTERRUPTIBLE); 2361 - if (wport->flags & DISABLED || 2362 - file->f_flags & O_NONBLOCK) { 2363 - current->state = TASK_RUNNING; 2364 - remove_wait_queue(&wport->queue, &wait); 2365 - return ret ? ret : -EAGAIN; 2366 - } 2367 - schedule(); 2368 - if (signal_pending(current)) { 2369 - current->state = TASK_RUNNING; 2370 - remove_wait_queue(&wport->queue, &wait); 2371 - return ret ? ret : -ERESTARTSYS; 2372 - } 2373 - } 2374 - current->state = TASK_RUNNING; 2375 - remove_wait_queue(&wport->queue, &wait); 2376 - /* nb bytes are available in userbuf. */ 2377 - if (nb > count) 2378 - nb = count; 2379 - DBGPV("nb = %d\n", nb); 2380 - if (copy_from_user(wport->swbuf + wport->swb_u_idx, buffer, nb)) 2381 - return -EFAULT; 2382 - pcm_output(devc, 0, nb); 2383 - buffer += nb; 2384 - count -= nb; 2385 - ret += nb; 2386 - } 2387 - DBGPV("returning %d\n", ret); 2388 - return ret; 2389 - } 2390 - 2391 - static ssize_t vwsnd_audio_write(struct file *file, 2392 - const char *buffer, 2393 - size_t count, 2394 - loff_t *ppos) 2395 - { 2396 - vwsnd_dev_t *devc = file->private_data; 2397 - ssize_t ret; 2398 - 2399 - mutex_lock(&devc->io_mutex); 2400 - ret = vwsnd_audio_do_write(file, buffer, count, ppos); 2401 - mutex_unlock(&devc->io_mutex); 2402 - return ret; 2403 - } 2404 - 2405 - /* No kernel lock - fine */ 2406 - static unsigned int vwsnd_audio_poll(struct file *file, 2407 - struct poll_table_struct *wait) 2408 - { 2409 - vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; 2410 - vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ? 2411 - &devc->rport : NULL; 2412 - vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ? 2413 - &devc->wport : NULL; 2414 - unsigned int mask = 0; 2415 - 2416 - DBGEV("(file=0x%p, wait=0x%p)\n", file, wait); 2417 - 2418 - ASSERT(rport || wport); 2419 - if (rport) { 2420 - poll_wait(file, &rport->queue, wait); 2421 - if (swb_inc_u(rport, 0)) 2422 - mask |= (POLLIN | POLLRDNORM); 2423 - } 2424 - if (wport) { 2425 - poll_wait(file, &wport->queue, wait); 2426 - if (wport->swbuf == NULL || swb_inc_u(wport, 0)) 2427 - mask |= (POLLOUT | POLLWRNORM); 2428 - } 2429 - 2430 - DBGPV("returning 0x%x\n", mask); 2431 - return mask; 2432 - } 2433 - 2434 - static int vwsnd_audio_do_ioctl(struct file *file, 2435 - unsigned int cmd, 2436 - unsigned long arg) 2437 - { 2438 - vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; 2439 - vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ? 2440 - &devc->rport : NULL; 2441 - vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ? 2442 - &devc->wport : NULL; 2443 - vwsnd_port_t *aport = rport ? rport : wport; 2444 - struct audio_buf_info buf_info; 2445 - struct count_info info; 2446 - unsigned long flags; 2447 - int ival; 2448 - 2449 - 2450 - DBGEV("(file=0x%p, cmd=0x%x, arg=0x%lx)\n", 2451 - file, cmd, arg); 2452 - switch (cmd) { 2453 - case OSS_GETVERSION: /* _SIOR ('M', 118, int) */ 2454 - DBGX("OSS_GETVERSION\n"); 2455 - ival = SOUND_VERSION; 2456 - return put_user(ival, (int *) arg); 2457 - 2458 - case SNDCTL_DSP_GETCAPS: /* _SIOR ('P',15, int) */ 2459 - DBGX("SNDCTL_DSP_GETCAPS\n"); 2460 - ival = DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER; 2461 - return put_user(ival, (int *) arg); 2462 - 2463 - case SNDCTL_DSP_GETFMTS: /* _SIOR ('P',11, int) */ 2464 - DBGX("SNDCTL_DSP_GETFMTS\n"); 2465 - ival = (AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | 2466 - AFMT_U8 | AFMT_S8); 2467 - return put_user(ival, (int *) arg); 2468 - break; 2469 - 2470 - case SOUND_PCM_READ_RATE: /* _SIOR ('P', 2, int) */ 2471 - DBGX("SOUND_PCM_READ_RATE\n"); 2472 - ival = aport->sw_framerate; 2473 - return put_user(ival, (int *) arg); 2474 - 2475 - case SOUND_PCM_READ_CHANNELS: /* _SIOR ('P', 6, int) */ 2476 - DBGX("SOUND_PCM_READ_CHANNELS\n"); 2477 - ival = aport->sw_channels; 2478 - return put_user(ival, (int *) arg); 2479 - 2480 - case SNDCTL_DSP_SPEED: /* _SIOWR('P', 2, int) */ 2481 - if (get_user(ival, (int *) arg)) 2482 - return -EFAULT; 2483 - DBGX("SNDCTL_DSP_SPEED %d\n", ival); 2484 - if (ival) { 2485 - if (aport->swstate != SW_INITIAL) { 2486 - DBGX("SNDCTL_DSP_SPEED failed: swstate = %d\n", 2487 - aport->swstate); 2488 - return -EINVAL; 2489 - } 2490 - if (ival < MIN_SPEED) 2491 - ival = MIN_SPEED; 2492 - if (ival > MAX_SPEED) 2493 - ival = MAX_SPEED; 2494 - if (rport) 2495 - rport->sw_framerate = ival; 2496 - if (wport) 2497 - wport->sw_framerate = ival; 2498 - } else 2499 - ival = aport->sw_framerate; 2500 - return put_user(ival, (int *) arg); 2501 - 2502 - case SNDCTL_DSP_STEREO: /* _SIOWR('P', 3, int) */ 2503 - if (get_user(ival, (int *) arg)) 2504 - return -EFAULT; 2505 - DBGX("SNDCTL_DSP_STEREO %d\n", ival); 2506 - if (ival != 0 && ival != 1) 2507 - return -EINVAL; 2508 - if (aport->swstate != SW_INITIAL) 2509 - return -EINVAL; 2510 - if (rport) 2511 - rport->sw_channels = ival + 1; 2512 - if (wport) 2513 - wport->sw_channels = ival + 1; 2514 - return put_user(ival, (int *) arg); 2515 - 2516 - case SNDCTL_DSP_CHANNELS: /* _SIOWR('P', 6, int) */ 2517 - if (get_user(ival, (int *) arg)) 2518 - return -EFAULT; 2519 - DBGX("SNDCTL_DSP_CHANNELS %d\n", ival); 2520 - if (ival != 1 && ival != 2) 2521 - return -EINVAL; 2522 - if (aport->swstate != SW_INITIAL) 2523 - return -EINVAL; 2524 - if (rport) 2525 - rport->sw_channels = ival; 2526 - if (wport) 2527 - wport->sw_channels = ival; 2528 - return put_user(ival, (int *) arg); 2529 - 2530 - case SNDCTL_DSP_GETBLKSIZE: /* _SIOWR('P', 4, int) */ 2531 - ival = pcm_setup(devc, rport, wport); 2532 - if (ival < 0) { 2533 - DBGX("SNDCTL_DSP_GETBLKSIZE failed, errno %d\n", ival); 2534 - return ival; 2535 - } 2536 - ival = 1 << aport->sw_fragshift; 2537 - DBGX("SNDCTL_DSP_GETBLKSIZE returning %d\n", ival); 2538 - return put_user(ival, (int *) arg); 2539 - 2540 - case SNDCTL_DSP_SETFRAGMENT: /* _SIOWR('P',10, int) */ 2541 - if (get_user(ival, (int *) arg)) 2542 - return -EFAULT; 2543 - DBGX("SNDCTL_DSP_SETFRAGMENT %d:%d\n", 2544 - ival >> 16, ival & 0xFFFF); 2545 - if (aport->swstate != SW_INITIAL) 2546 - return -EINVAL; 2547 - { 2548 - int sw_fragshift = ival & 0xFFFF; 2549 - int sw_subdivshift = aport->sw_subdivshift; 2550 - int hw_fragshift = sw_fragshift - sw_subdivshift; 2551 - int sw_fragcount = (ival >> 16) & 0xFFFF; 2552 - int hw_fragsize; 2553 - if (hw_fragshift < MIN_FRAGSHIFT) 2554 - hw_fragshift = MIN_FRAGSHIFT; 2555 - if (hw_fragshift > MAX_FRAGSHIFT) 2556 - hw_fragshift = MAX_FRAGSHIFT; 2557 - sw_fragshift = hw_fragshift + aport->sw_subdivshift; 2558 - hw_fragsize = 1 << hw_fragshift; 2559 - if (sw_fragcount < MIN_FRAGCOUNT(hw_fragsize)) 2560 - sw_fragcount = MIN_FRAGCOUNT(hw_fragsize); 2561 - if (sw_fragcount > MAX_FRAGCOUNT(hw_fragsize)) 2562 - sw_fragcount = MAX_FRAGCOUNT(hw_fragsize); 2563 - DBGPV("sw_fragshift = %d\n", sw_fragshift); 2564 - DBGPV("rport = 0x%p, wport = 0x%p\n", rport, wport); 2565 - if (rport) { 2566 - rport->sw_fragshift = sw_fragshift; 2567 - rport->sw_fragcount = sw_fragcount; 2568 - } 2569 - if (wport) { 2570 - wport->sw_fragshift = sw_fragshift; 2571 - wport->sw_fragcount = sw_fragcount; 2572 - } 2573 - ival = sw_fragcount << 16 | sw_fragshift; 2574 - } 2575 - DBGX("SNDCTL_DSP_SETFRAGMENT returns %d:%d\n", 2576 - ival >> 16, ival & 0xFFFF); 2577 - return put_user(ival, (int *) arg); 2578 - 2579 - case SNDCTL_DSP_SUBDIVIDE: /* _SIOWR('P', 9, int) */ 2580 - if (get_user(ival, (int *) arg)) 2581 - return -EFAULT; 2582 - DBGX("SNDCTL_DSP_SUBDIVIDE %d\n", ival); 2583 - if (aport->swstate != SW_INITIAL) 2584 - return -EINVAL; 2585 - { 2586 - int subdivshift; 2587 - int hw_fragshift, hw_fragsize, hw_fragcount; 2588 - switch (ival) { 2589 - case 1: subdivshift = 0; break; 2590 - case 2: subdivshift = 1; break; 2591 - case 4: subdivshift = 2; break; 2592 - default: return -EINVAL; 2593 - } 2594 - hw_fragshift = aport->sw_fragshift - subdivshift; 2595 - if (hw_fragshift < MIN_FRAGSHIFT || 2596 - hw_fragshift > MAX_FRAGSHIFT) 2597 - return -EINVAL; 2598 - hw_fragsize = 1 << hw_fragshift; 2599 - hw_fragcount = aport->sw_fragcount >> subdivshift; 2600 - if (hw_fragcount < MIN_FRAGCOUNT(hw_fragsize) || 2601 - hw_fragcount > MAX_FRAGCOUNT(hw_fragsize)) 2602 - return -EINVAL; 2603 - if (rport) 2604 - rport->sw_subdivshift = subdivshift; 2605 - if (wport) 2606 - wport->sw_subdivshift = subdivshift; 2607 - } 2608 - return 0; 2609 - 2610 - case SNDCTL_DSP_SETFMT: /* _SIOWR('P',5, int) */ 2611 - if (get_user(ival, (int *) arg)) 2612 - return -EFAULT; 2613 - DBGX("SNDCTL_DSP_SETFMT %d\n", ival); 2614 - if (ival != AFMT_QUERY) { 2615 - if (aport->swstate != SW_INITIAL) { 2616 - DBGP("SETFMT failed, swstate = %d\n", 2617 - aport->swstate); 2618 - return -EINVAL; 2619 - } 2620 - switch (ival) { 2621 - case AFMT_MU_LAW: 2622 - case AFMT_A_LAW: 2623 - case AFMT_U8: 2624 - case AFMT_S8: 2625 - case AFMT_S16_LE: 2626 - if (rport) 2627 - rport->sw_samplefmt = ival; 2628 - if (wport) 2629 - wport->sw_samplefmt = ival; 2630 - break; 2631 - default: 2632 - return -EINVAL; 2633 - } 2634 - } 2635 - ival = aport->sw_samplefmt; 2636 - return put_user(ival, (int *) arg); 2637 - 2638 - case SNDCTL_DSP_GETOSPACE: /* _SIOR ('P',12, audio_buf_info) */ 2639 - DBGXV("SNDCTL_DSP_GETOSPACE\n"); 2640 - if (!wport) 2641 - return -EINVAL; 2642 - ival = pcm_setup(devc, rport, wport); 2643 - if (ival < 0) 2644 - return ival; 2645 - ival = swb_inc_u(wport, 0); 2646 - buf_info.fragments = ival >> wport->sw_fragshift; 2647 - buf_info.fragstotal = wport->sw_fragcount; 2648 - buf_info.fragsize = 1 << wport->sw_fragshift; 2649 - buf_info.bytes = ival; 2650 - DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n", 2651 - buf_info.fragments, buf_info.fragstotal, 2652 - buf_info.fragsize, buf_info.bytes); 2653 - if (copy_to_user((void *) arg, &buf_info, sizeof buf_info)) 2654 - return -EFAULT; 2655 - return 0; 2656 - 2657 - case SNDCTL_DSP_GETISPACE: /* _SIOR ('P',13, audio_buf_info) */ 2658 - DBGX("SNDCTL_DSP_GETISPACE\n"); 2659 - if (!rport) 2660 - return -EINVAL; 2661 - ival = pcm_setup(devc, rport, wport); 2662 - if (ival < 0) 2663 - return ival; 2664 - ival = swb_inc_u(rport, 0); 2665 - buf_info.fragments = ival >> rport->sw_fragshift; 2666 - buf_info.fragstotal = rport->sw_fragcount; 2667 - buf_info.fragsize = 1 << rport->sw_fragshift; 2668 - buf_info.bytes = ival; 2669 - DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n", 2670 - buf_info.fragments, buf_info.fragstotal, 2671 - buf_info.fragsize, buf_info.bytes); 2672 - if (copy_to_user((void *) arg, &buf_info, sizeof buf_info)) 2673 - return -EFAULT; 2674 - return 0; 2675 - 2676 - case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */ 2677 - DBGX("SNDCTL_DSP_NONBLOCK\n"); 2678 - spin_lock(&file->f_lock); 2679 - file->f_flags |= O_NONBLOCK; 2680 - spin_unlock(&file->f_lock); 2681 - return 0; 2682 - 2683 - case SNDCTL_DSP_RESET: /* _SIO ('P', 0) */ 2684 - DBGX("SNDCTL_DSP_RESET\n"); 2685 - /* 2686 - * Nothing special needs to be done for input. Input 2687 - * samples sit in swbuf, but it will be reinitialized 2688 - * to empty when pcm_setup() is called. 2689 - */ 2690 - if (wport && wport->swbuf) { 2691 - wport->swstate = SW_INITIAL; 2692 - pcm_output(devc, 0, 0); 2693 - pcm_write_sync(devc); 2694 - } 2695 - pcm_shutdown(devc, rport, wport); 2696 - return 0; 2697 - 2698 - case SNDCTL_DSP_SYNC: /* _SIO ('P', 1) */ 2699 - DBGX("SNDCTL_DSP_SYNC\n"); 2700 - if (wport) { 2701 - pcm_flush_frag(devc); 2702 - pcm_write_sync(devc); 2703 - } 2704 - pcm_shutdown(devc, rport, wport); 2705 - return 0; 2706 - 2707 - case SNDCTL_DSP_POST: /* _SIO ('P', 8) */ 2708 - DBGX("SNDCTL_DSP_POST\n"); 2709 - if (!wport) 2710 - return -EINVAL; 2711 - pcm_flush_frag(devc); 2712 - return 0; 2713 - 2714 - case SNDCTL_DSP_GETIPTR: /* _SIOR ('P', 17, count_info) */ 2715 - DBGX("SNDCTL_DSP_GETIPTR\n"); 2716 - if (!rport) 2717 - return -EINVAL; 2718 - spin_lock_irqsave(&rport->lock, flags); 2719 - { 2720 - ustmsc_t ustmsc; 2721 - if (rport->hwstate == HW_RUNNING) { 2722 - ASSERT(rport->swstate == SW_RUN); 2723 - li_read_USTMSC(&rport->chan, &ustmsc); 2724 - info.bytes = ustmsc.msc - rport->MSC_offset; 2725 - info.bytes *= rport->frame_size; 2726 - } else { 2727 - info.bytes = rport->byte_count; 2728 - } 2729 - info.blocks = rport->frag_count; 2730 - info.ptr = 0; /* not implemented */ 2731 - rport->frag_count = 0; 2732 - } 2733 - spin_unlock_irqrestore(&rport->lock, flags); 2734 - if (copy_to_user((void *) arg, &info, sizeof info)) 2735 - return -EFAULT; 2736 - return 0; 2737 - 2738 - case SNDCTL_DSP_GETOPTR: /* _SIOR ('P',18, count_info) */ 2739 - DBGX("SNDCTL_DSP_GETOPTR\n"); 2740 - if (!wport) 2741 - return -EINVAL; 2742 - spin_lock_irqsave(&wport->lock, flags); 2743 - { 2744 - ustmsc_t ustmsc; 2745 - if (wport->hwstate == HW_RUNNING) { 2746 - ASSERT(wport->swstate == SW_RUN); 2747 - li_read_USTMSC(&wport->chan, &ustmsc); 2748 - info.bytes = ustmsc.msc - wport->MSC_offset; 2749 - info.bytes *= wport->frame_size; 2750 - } else { 2751 - info.bytes = wport->byte_count; 2752 - } 2753 - info.blocks = wport->frag_count; 2754 - info.ptr = 0; /* not implemented */ 2755 - wport->frag_count = 0; 2756 - } 2757 - spin_unlock_irqrestore(&wport->lock, flags); 2758 - if (copy_to_user((void *) arg, &info, sizeof info)) 2759 - return -EFAULT; 2760 - return 0; 2761 - 2762 - case SNDCTL_DSP_GETODELAY: /* _SIOR ('P', 23, int) */ 2763 - DBGX("SNDCTL_DSP_GETODELAY\n"); 2764 - if (!wport) 2765 - return -EINVAL; 2766 - spin_lock_irqsave(&wport->lock, flags); 2767 - { 2768 - int fsize = wport->frame_size; 2769 - ival = wport->swb_i_avail / fsize; 2770 - if (wport->hwstate == HW_RUNNING) { 2771 - int swptr, hwptr, hwframes, hwbytes, hwsize; 2772 - int totalhwbytes; 2773 - ustmsc_t ustmsc; 2774 - 2775 - hwsize = wport->hwbuf_size; 2776 - swptr = li_read_swptr(&wport->chan); 2777 - li_read_USTMSC(&wport->chan, &ustmsc); 2778 - hwframes = ustmsc.msc - wport->MSC_offset; 2779 - totalhwbytes = hwframes * fsize; 2780 - hwptr = totalhwbytes % hwsize; 2781 - hwbytes = (swptr - hwptr + hwsize) % hwsize; 2782 - ival += hwbytes / fsize; 2783 - } 2784 - } 2785 - spin_unlock_irqrestore(&wport->lock, flags); 2786 - return put_user(ival, (int *) arg); 2787 - 2788 - case SNDCTL_DSP_PROFILE: /* _SIOW ('P', 23, int) */ 2789 - DBGX("SNDCTL_DSP_PROFILE\n"); 2790 - 2791 - /* 2792 - * Thomas Sailer explains SNDCTL_DSP_PROFILE 2793 - * (private email, March 24, 1999): 2794 - * 2795 - * This gives the sound driver a hint on what it 2796 - * should do with partial fragments 2797 - * (i.e. fragments partially filled with write). 2798 - * This can direct the driver to zero them or 2799 - * leave them alone. But don't ask me what this 2800 - * is good for, my driver just zeroes the last 2801 - * fragment before the receiver stops, no idea 2802 - * what good for any other behaviour could 2803 - * be. Implementing it as NOP seems safe. 2804 - */ 2805 - 2806 - break; 2807 - 2808 - case SNDCTL_DSP_GETTRIGGER: /* _SIOR ('P',16, int) */ 2809 - DBGX("SNDCTL_DSP_GETTRIGGER\n"); 2810 - ival = 0; 2811 - if (rport) { 2812 - spin_lock_irqsave(&rport->lock, flags); 2813 - { 2814 - if (!(rport->flags & DISABLED)) 2815 - ival |= PCM_ENABLE_INPUT; 2816 - } 2817 - spin_unlock_irqrestore(&rport->lock, flags); 2818 - } 2819 - if (wport) { 2820 - spin_lock_irqsave(&wport->lock, flags); 2821 - { 2822 - if (!(wport->flags & DISABLED)) 2823 - ival |= PCM_ENABLE_OUTPUT; 2824 - } 2825 - spin_unlock_irqrestore(&wport->lock, flags); 2826 - } 2827 - return put_user(ival, (int *) arg); 2828 - 2829 - case SNDCTL_DSP_SETTRIGGER: /* _SIOW ('P',16, int) */ 2830 - if (get_user(ival, (int *) arg)) 2831 - return -EFAULT; 2832 - DBGX("SNDCTL_DSP_SETTRIGGER %d\n", ival); 2833 - 2834 - /* 2835 - * If user is disabling I/O and port is not in initial 2836 - * state, fail with EINVAL. 2837 - */ 2838 - 2839 - if (((rport && !(ival & PCM_ENABLE_INPUT)) || 2840 - (wport && !(ival & PCM_ENABLE_OUTPUT))) && 2841 - aport->swstate != SW_INITIAL) 2842 - return -EINVAL; 2843 - 2844 - if (rport) { 2845 - vwsnd_port_hwstate_t hwstate; 2846 - spin_lock_irqsave(&rport->lock, flags); 2847 - { 2848 - hwstate = rport->hwstate; 2849 - if (ival & PCM_ENABLE_INPUT) 2850 - rport->flags &= ~DISABLED; 2851 - else 2852 - rport->flags |= DISABLED; 2853 - } 2854 - spin_unlock_irqrestore(&rport->lock, flags); 2855 - if (hwstate != HW_RUNNING && ival & PCM_ENABLE_INPUT) { 2856 - 2857 - if (rport->swstate == SW_INITIAL) 2858 - pcm_setup(devc, rport, wport); 2859 - else 2860 - li_activate_dma(&rport->chan); 2861 - } 2862 - } 2863 - if (wport) { 2864 - vwsnd_port_flags_t pflags; 2865 - spin_lock_irqsave(&wport->lock, flags); 2866 - { 2867 - pflags = wport->flags; 2868 - if (ival & PCM_ENABLE_OUTPUT) 2869 - wport->flags &= ~DISABLED; 2870 - else 2871 - wport->flags |= DISABLED; 2872 - } 2873 - spin_unlock_irqrestore(&wport->lock, flags); 2874 - if (pflags & DISABLED && ival & PCM_ENABLE_OUTPUT) { 2875 - if (wport->swstate == SW_RUN) 2876 - pcm_output(devc, 0, 0); 2877 - } 2878 - } 2879 - return 0; 2880 - 2881 - default: 2882 - DBGP("unknown ioctl 0x%x\n", cmd); 2883 - return -EINVAL; 2884 - } 2885 - DBGP("unimplemented ioctl 0x%x\n", cmd); 2886 - return -EINVAL; 2887 - } 2888 - 2889 - static long vwsnd_audio_ioctl(struct file *file, 2890 - unsigned int cmd, 2891 - unsigned long arg) 2892 - { 2893 - vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; 2894 - int ret; 2895 - 2896 - mutex_lock(&vwsnd_mutex); 2897 - mutex_lock(&devc->io_mutex); 2898 - ret = vwsnd_audio_do_ioctl(file, cmd, arg); 2899 - mutex_unlock(&devc->io_mutex); 2900 - mutex_unlock(&vwsnd_mutex); 2901 - 2902 - return ret; 2903 - } 2904 - 2905 - /* No mmap. */ 2906 - 2907 - static int vwsnd_audio_mmap(struct file *file, struct vm_area_struct *vma) 2908 - { 2909 - DBGE("(file=0x%p, vma=0x%p)\n", file, vma); 2910 - return -ENODEV; 2911 - } 2912 - 2913 - /* 2914 - * Open the audio device for read and/or write. 2915 - * 2916 - * Returns 0 on success, -errno on failure. 2917 - */ 2918 - 2919 - static int vwsnd_audio_open(struct inode *inode, struct file *file) 2920 - { 2921 - vwsnd_dev_t *devc; 2922 - int minor = iminor(inode); 2923 - int sw_samplefmt; 2924 - DEFINE_WAIT(wait); 2925 - 2926 - DBGE("(inode=0x%p, file=0x%p)\n", inode, file); 2927 - 2928 - mutex_lock(&vwsnd_mutex); 2929 - INC_USE_COUNT; 2930 - for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 2931 - if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F)) 2932 - break; 2933 - 2934 - if (devc == NULL) { 2935 - DEC_USE_COUNT; 2936 - mutex_unlock(&vwsnd_mutex); 2937 - return -ENODEV; 2938 - } 2939 - 2940 - mutex_lock(&devc->open_mutex); 2941 - while (1) { 2942 - prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE); 2943 - if (!(devc->open_mode & file->f_mode)) 2944 - break; 2945 - 2946 - mutex_unlock(&devc->open_mutex); 2947 - mutex_unlock(&vwsnd_mutex); 2948 - if (file->f_flags & O_NONBLOCK) { 2949 - DEC_USE_COUNT; 2950 - return -EBUSY; 2951 - } 2952 - schedule(); 2953 - if (signal_pending(current)) { 2954 - DEC_USE_COUNT; 2955 - return -ERESTARTSYS; 2956 - } 2957 - mutex_lock(&vwsnd_mutex); 2958 - mutex_lock(&devc->open_mutex); 2959 - } 2960 - finish_wait(&devc->open_wait, &wait); 2961 - devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 2962 - mutex_unlock(&devc->open_mutex); 2963 - 2964 - /* get default sample format from minor number. */ 2965 - 2966 - sw_samplefmt = 0; 2967 - if ((minor & 0xF) == SND_DEV_DSP) 2968 - sw_samplefmt = AFMT_U8; 2969 - else if ((minor & 0xF) == SND_DEV_AUDIO) 2970 - sw_samplefmt = AFMT_MU_LAW; 2971 - else if ((minor & 0xF) == SND_DEV_DSP16) 2972 - sw_samplefmt = AFMT_S16_LE; 2973 - else 2974 - ASSERT(0); 2975 - 2976 - /* Initialize vwsnd_ports. */ 2977 - 2978 - mutex_lock(&devc->io_mutex); 2979 - { 2980 - if (file->f_mode & FMODE_READ) { 2981 - devc->rport.swstate = SW_INITIAL; 2982 - devc->rport.flags = 0; 2983 - devc->rport.sw_channels = 1; 2984 - devc->rport.sw_samplefmt = sw_samplefmt; 2985 - devc->rport.sw_framerate = 8000; 2986 - devc->rport.sw_fragshift = DEFAULT_FRAGSHIFT; 2987 - devc->rport.sw_fragcount = DEFAULT_FRAGCOUNT; 2988 - devc->rport.sw_subdivshift = DEFAULT_SUBDIVSHIFT; 2989 - devc->rport.byte_count = 0; 2990 - devc->rport.frag_count = 0; 2991 - } 2992 - if (file->f_mode & FMODE_WRITE) { 2993 - devc->wport.swstate = SW_INITIAL; 2994 - devc->wport.flags = 0; 2995 - devc->wport.sw_channels = 1; 2996 - devc->wport.sw_samplefmt = sw_samplefmt; 2997 - devc->wport.sw_framerate = 8000; 2998 - devc->wport.sw_fragshift = DEFAULT_FRAGSHIFT; 2999 - devc->wport.sw_fragcount = DEFAULT_FRAGCOUNT; 3000 - devc->wport.sw_subdivshift = DEFAULT_SUBDIVSHIFT; 3001 - devc->wport.byte_count = 0; 3002 - devc->wport.frag_count = 0; 3003 - } 3004 - } 3005 - mutex_unlock(&devc->io_mutex); 3006 - 3007 - file->private_data = devc; 3008 - DBGRV(); 3009 - mutex_unlock(&vwsnd_mutex); 3010 - return 0; 3011 - } 3012 - 3013 - /* 3014 - * Release (close) the audio device. 3015 - */ 3016 - 3017 - static int vwsnd_audio_release(struct inode *inode, struct file *file) 3018 - { 3019 - vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; 3020 - vwsnd_port_t *wport = NULL, *rport = NULL; 3021 - int err = 0; 3022 - 3023 - mutex_lock(&vwsnd_mutex); 3024 - mutex_lock(&devc->io_mutex); 3025 - { 3026 - DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3027 - 3028 - if (file->f_mode & FMODE_READ) 3029 - rport = &devc->rport; 3030 - if (file->f_mode & FMODE_WRITE) { 3031 - wport = &devc->wport; 3032 - pcm_flush_frag(devc); 3033 - pcm_write_sync(devc); 3034 - } 3035 - pcm_shutdown(devc, rport, wport); 3036 - if (rport) 3037 - rport->swstate = SW_OFF; 3038 - if (wport) 3039 - wport->swstate = SW_OFF; 3040 - } 3041 - mutex_unlock(&devc->io_mutex); 3042 - 3043 - mutex_lock(&devc->open_mutex); 3044 - { 3045 - devc->open_mode &= ~file->f_mode; 3046 - } 3047 - mutex_unlock(&devc->open_mutex); 3048 - wake_up(&devc->open_wait); 3049 - DEC_USE_COUNT; 3050 - DBGR(); 3051 - mutex_unlock(&vwsnd_mutex); 3052 - return err; 3053 - } 3054 - 3055 - static const struct file_operations vwsnd_audio_fops = { 3056 - .owner = THIS_MODULE, 3057 - .llseek = no_llseek, 3058 - .read = vwsnd_audio_read, 3059 - .write = vwsnd_audio_write, 3060 - .poll = vwsnd_audio_poll, 3061 - .unlocked_ioctl = vwsnd_audio_ioctl, 3062 - .mmap = vwsnd_audio_mmap, 3063 - .open = vwsnd_audio_open, 3064 - .release = vwsnd_audio_release, 3065 - }; 3066 - 3067 - /*****************************************************************************/ 3068 - /* mixer driver */ 3069 - 3070 - /* open the mixer device. */ 3071 - 3072 - static int vwsnd_mixer_open(struct inode *inode, struct file *file) 3073 - { 3074 - vwsnd_dev_t *devc; 3075 - 3076 - DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3077 - 3078 - INC_USE_COUNT; 3079 - mutex_lock(&vwsnd_mutex); 3080 - for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 3081 - if (devc->mixer_minor == iminor(inode)) 3082 - break; 3083 - 3084 - if (devc == NULL) { 3085 - DEC_USE_COUNT; 3086 - mutex_unlock(&vwsnd_mutex); 3087 - return -ENODEV; 3088 - } 3089 - file->private_data = devc; 3090 - mutex_unlock(&vwsnd_mutex); 3091 - return 0; 3092 - } 3093 - 3094 - /* release (close) the mixer device. */ 3095 - 3096 - static int vwsnd_mixer_release(struct inode *inode, struct file *file) 3097 - { 3098 - DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3099 - DEC_USE_COUNT; 3100 - return 0; 3101 - } 3102 - 3103 - /* mixer_read_ioctl handles all read ioctls on the mixer device. */ 3104 - 3105 - static int mixer_read_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *arg) 3106 - { 3107 - int val = -1; 3108 - 3109 - DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg); 3110 - 3111 - switch (nr) { 3112 - case SOUND_MIXER_CAPS: 3113 - val = SOUND_CAP_EXCL_INPUT; 3114 - break; 3115 - 3116 - case SOUND_MIXER_DEVMASK: 3117 - val = (SOUND_MASK_PCM | SOUND_MASK_LINE | 3118 - SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV); 3119 - break; 3120 - 3121 - case SOUND_MIXER_STEREODEVS: 3122 - val = (SOUND_MASK_PCM | SOUND_MASK_LINE | 3123 - SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV); 3124 - break; 3125 - 3126 - case SOUND_MIXER_OUTMASK: 3127 - val = (SOUND_MASK_PCM | SOUND_MASK_LINE | 3128 - SOUND_MASK_MIC | SOUND_MASK_CD); 3129 - break; 3130 - 3131 - case SOUND_MIXER_RECMASK: 3132 - val = (SOUND_MASK_PCM | SOUND_MASK_LINE | 3133 - SOUND_MASK_MIC | SOUND_MASK_CD); 3134 - break; 3135 - 3136 - case SOUND_MIXER_PCM: 3137 - val = ad1843_get_gain(&devc->lith, &ad1843_gain_PCM); 3138 - break; 3139 - 3140 - case SOUND_MIXER_LINE: 3141 - val = ad1843_get_gain(&devc->lith, &ad1843_gain_LINE); 3142 - break; 3143 - 3144 - case SOUND_MIXER_MIC: 3145 - val = ad1843_get_gain(&devc->lith, &ad1843_gain_MIC); 3146 - break; 3147 - 3148 - case SOUND_MIXER_CD: 3149 - val = ad1843_get_gain(&devc->lith, &ad1843_gain_CD); 3150 - break; 3151 - 3152 - case SOUND_MIXER_RECLEV: 3153 - val = ad1843_get_gain(&devc->lith, &ad1843_gain_RECLEV); 3154 - break; 3155 - 3156 - case SOUND_MIXER_RECSRC: 3157 - val = ad1843_get_recsrc(&devc->lith); 3158 - break; 3159 - 3160 - case SOUND_MIXER_OUTSRC: 3161 - val = ad1843_get_outsrc(&devc->lith); 3162 - break; 3163 - 3164 - default: 3165 - return -EINVAL; 3166 - } 3167 - return put_user(val, (int __user *) arg); 3168 - } 3169 - 3170 - /* mixer_write_ioctl handles all write ioctls on the mixer device. */ 3171 - 3172 - static int mixer_write_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *arg) 3173 - { 3174 - int val; 3175 - int err; 3176 - 3177 - DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg); 3178 - 3179 - err = get_user(val, (int __user *) arg); 3180 - if (err) 3181 - return -EFAULT; 3182 - switch (nr) { 3183 - case SOUND_MIXER_PCM: 3184 - val = ad1843_set_gain(&devc->lith, &ad1843_gain_PCM, val); 3185 - break; 3186 - 3187 - case SOUND_MIXER_LINE: 3188 - val = ad1843_set_gain(&devc->lith, &ad1843_gain_LINE, val); 3189 - break; 3190 - 3191 - case SOUND_MIXER_MIC: 3192 - val = ad1843_set_gain(&devc->lith, &ad1843_gain_MIC, val); 3193 - break; 3194 - 3195 - case SOUND_MIXER_CD: 3196 - val = ad1843_set_gain(&devc->lith, &ad1843_gain_CD, val); 3197 - break; 3198 - 3199 - case SOUND_MIXER_RECLEV: 3200 - val = ad1843_set_gain(&devc->lith, &ad1843_gain_RECLEV, val); 3201 - break; 3202 - 3203 - case SOUND_MIXER_RECSRC: 3204 - if (devc->rport.swbuf || devc->wport.swbuf) 3205 - return -EBUSY; /* can't change recsrc while running */ 3206 - val = ad1843_set_recsrc(&devc->lith, val); 3207 - break; 3208 - 3209 - case SOUND_MIXER_OUTSRC: 3210 - val = ad1843_set_outsrc(&devc->lith, val); 3211 - break; 3212 - 3213 - default: 3214 - return -EINVAL; 3215 - } 3216 - if (val < 0) 3217 - return val; 3218 - return put_user(val, (int __user *) arg); 3219 - } 3220 - 3221 - /* This is the ioctl entry to the mixer driver. */ 3222 - 3223 - static long vwsnd_mixer_ioctl(struct file *file, 3224 - unsigned int cmd, 3225 - unsigned long arg) 3226 - { 3227 - vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; 3228 - const unsigned int nrmask = _IOC_NRMASK << _IOC_NRSHIFT; 3229 - const unsigned int nr = (cmd & nrmask) >> _IOC_NRSHIFT; 3230 - int retval; 3231 - 3232 - DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg); 3233 - 3234 - mutex_lock(&vwsnd_mutex); 3235 - mutex_lock(&devc->mix_mutex); 3236 - { 3237 - if ((cmd & ~nrmask) == MIXER_READ(0)) 3238 - retval = mixer_read_ioctl(devc, nr, (void __user *) arg); 3239 - else if ((cmd & ~nrmask) == MIXER_WRITE(0)) 3240 - retval = mixer_write_ioctl(devc, nr, (void __user *) arg); 3241 - else 3242 - retval = -EINVAL; 3243 - } 3244 - mutex_unlock(&devc->mix_mutex); 3245 - mutex_unlock(&vwsnd_mutex); 3246 - return retval; 3247 - } 3248 - 3249 - static const struct file_operations vwsnd_mixer_fops = { 3250 - .owner = THIS_MODULE, 3251 - .llseek = no_llseek, 3252 - .unlocked_ioctl = vwsnd_mixer_ioctl, 3253 - .open = vwsnd_mixer_open, 3254 - .release = vwsnd_mixer_release, 3255 - }; 3256 - 3257 - /*****************************************************************************/ 3258 - /* probe/attach/unload */ 3259 - 3260 - /* driver probe routine. Return nonzero if hardware is found. */ 3261 - 3262 - static int __init probe_vwsnd(struct address_info *hw_config) 3263 - { 3264 - lithium_t lith; 3265 - int w; 3266 - unsigned long later; 3267 - 3268 - DBGEV("(hw_config=0x%p)\n", hw_config); 3269 - 3270 - /* XXX verify lithium present (to prevent crash on non-vw) */ 3271 - 3272 - if (li_create(&lith, hw_config->io_base) != 0) { 3273 - printk(KERN_WARNING "probe_vwsnd: can't map lithium\n"); 3274 - return 0; 3275 - } 3276 - later = jiffies + 2; 3277 - li_writel(&lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE); 3278 - do { 3279 - w = li_readl(&lith, LI_HOST_CONTROLLER); 3280 - } while (w == LI_HC_LINK_ENABLE && time_before(jiffies, later)); 3281 - 3282 - li_destroy(&lith); 3283 - 3284 - DBGPV("HC = 0x%04x\n", w); 3285 - 3286 - if ((w == LI_HC_LINK_ENABLE) || (w & LI_HC_LINK_CODEC)) { 3287 - 3288 - /* This may indicate a beta machine with no audio, 3289 - * or a future machine with different audio. 3290 - * On beta-release 320 w/ no audio, HC == 0x4000 */ 3291 - 3292 - printk(KERN_WARNING "probe_vwsnd: audio codec not found\n"); 3293 - return 0; 3294 - } 3295 - 3296 - if (w & LI_HC_LINK_FAILURE) { 3297 - printk(KERN_WARNING "probe_vwsnd: can't init audio codec\n"); 3298 - return 0; 3299 - } 3300 - 3301 - printk(KERN_INFO "vwsnd: lithium audio at mmio %#x irq %d\n", 3302 - hw_config->io_base, hw_config->irq); 3303 - 3304 - return 1; 3305 - } 3306 - 3307 - /* 3308 - * driver attach routine. Initialize driver data structures and 3309 - * initialize hardware. A new vwsnd_dev_t is allocated and put 3310 - * onto the global list, vwsnd_dev_list. 3311 - * 3312 - * Return +minor_dev on success, -errno on failure. 3313 - */ 3314 - 3315 - static int __init attach_vwsnd(struct address_info *hw_config) 3316 - { 3317 - vwsnd_dev_t *devc = NULL; 3318 - int err = -ENOMEM; 3319 - 3320 - DBGEV("(hw_config=0x%p)\n", hw_config); 3321 - 3322 - devc = kmalloc(sizeof (vwsnd_dev_t), GFP_KERNEL); 3323 - if (devc == NULL) 3324 - goto fail0; 3325 - 3326 - err = li_create(&devc->lith, hw_config->io_base); 3327 - if (err) 3328 - goto fail1; 3329 - 3330 - init_waitqueue_head(&devc->open_wait); 3331 - 3332 - devc->rport.hwbuf_size = HWBUF_SIZE; 3333 - devc->rport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER); 3334 - if (!devc->rport.hwbuf_vaddr) 3335 - goto fail2; 3336 - devc->rport.hwbuf = (void *) devc->rport.hwbuf_vaddr; 3337 - devc->rport.hwbuf_paddr = virt_to_phys(devc->rport.hwbuf); 3338 - 3339 - /* 3340 - * Quote from the NT driver: 3341 - * 3342 - * // WARNING!!! HACK to setup output dma!!! 3343 - * // This is required because even on output there is some data 3344 - * // trickling into the input DMA channel. This is a bug in the 3345 - * // Lithium microcode. 3346 - * // --sde 3347 - * 3348 - * We set the input side's DMA base address here. It will remain 3349 - * valid until the driver is unloaded. 3350 - */ 3351 - 3352 - li_writel(&devc->lith, LI_COMM1_BASE, 3353 - devc->rport.hwbuf_paddr >> 8 | 1 << (37 - 8)); 3354 - 3355 - devc->wport.hwbuf_size = HWBUF_SIZE; 3356 - devc->wport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER); 3357 - if (!devc->wport.hwbuf_vaddr) 3358 - goto fail3; 3359 - devc->wport.hwbuf = (void *) devc->wport.hwbuf_vaddr; 3360 - devc->wport.hwbuf_paddr = virt_to_phys(devc->wport.hwbuf); 3361 - DBGP("wport hwbuf = 0x%p\n", devc->wport.hwbuf); 3362 - 3363 - DBGDO(shut_up++); 3364 - err = ad1843_init(&devc->lith); 3365 - DBGDO(shut_up--); 3366 - if (err) 3367 - goto fail4; 3368 - 3369 - /* install interrupt handler */ 3370 - 3371 - err = request_irq(hw_config->irq, vwsnd_audio_intr, 0, "vwsnd", devc); 3372 - if (err) 3373 - goto fail5; 3374 - 3375 - /* register this device's drivers. */ 3376 - 3377 - devc->audio_minor = register_sound_dsp(&vwsnd_audio_fops, -1); 3378 - if ((err = devc->audio_minor) < 0) { 3379 - DBGDO(printk(KERN_WARNING 3380 - "attach_vwsnd: register_sound_dsp error %d\n", 3381 - err)); 3382 - goto fail6; 3383 - } 3384 - devc->mixer_minor = register_sound_mixer(&vwsnd_mixer_fops, 3385 - devc->audio_minor >> 4); 3386 - if ((err = devc->mixer_minor) < 0) { 3387 - DBGDO(printk(KERN_WARNING 3388 - "attach_vwsnd: register_sound_mixer error %d\n", 3389 - err)); 3390 - goto fail7; 3391 - } 3392 - 3393 - /* Squirrel away device indices for unload routine. */ 3394 - 3395 - hw_config->slots[0] = devc->audio_minor; 3396 - 3397 - /* Initialize as much of *devc as possible */ 3398 - 3399 - mutex_init(&devc->open_mutex); 3400 - mutex_init(&devc->io_mutex); 3401 - mutex_init(&devc->mix_mutex); 3402 - devc->open_mode = 0; 3403 - spin_lock_init(&devc->rport.lock); 3404 - init_waitqueue_head(&devc->rport.queue); 3405 - devc->rport.swstate = SW_OFF; 3406 - devc->rport.hwstate = HW_STOPPED; 3407 - devc->rport.flags = 0; 3408 - devc->rport.swbuf = NULL; 3409 - spin_lock_init(&devc->wport.lock); 3410 - init_waitqueue_head(&devc->wport.queue); 3411 - devc->wport.swstate = SW_OFF; 3412 - devc->wport.hwstate = HW_STOPPED; 3413 - devc->wport.flags = 0; 3414 - devc->wport.swbuf = NULL; 3415 - 3416 - /* Success. Link us onto the local device list. */ 3417 - 3418 - devc->next_dev = vwsnd_dev_list; 3419 - vwsnd_dev_list = devc; 3420 - return devc->audio_minor; 3421 - 3422 - /* So many ways to fail. Undo what we did. */ 3423 - 3424 - fail7: 3425 - unregister_sound_dsp(devc->audio_minor); 3426 - fail6: 3427 - free_irq(hw_config->irq, devc); 3428 - fail5: 3429 - fail4: 3430 - free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER); 3431 - fail3: 3432 - free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER); 3433 - fail2: 3434 - li_destroy(&devc->lith); 3435 - fail1: 3436 - kfree(devc); 3437 - fail0: 3438 - return err; 3439 - } 3440 - 3441 - static int __exit unload_vwsnd(struct address_info *hw_config) 3442 - { 3443 - vwsnd_dev_t *devc, **devcp; 3444 - 3445 - DBGE("()\n"); 3446 - 3447 - devcp = &vwsnd_dev_list; 3448 - while ((devc = *devcp)) { 3449 - if (devc->audio_minor == hw_config->slots[0]) { 3450 - *devcp = devc->next_dev; 3451 - break; 3452 - } 3453 - devcp = &devc->next_dev; 3454 - } 3455 - 3456 - if (!devc) 3457 - return -ENODEV; 3458 - 3459 - unregister_sound_mixer(devc->mixer_minor); 3460 - unregister_sound_dsp(devc->audio_minor); 3461 - free_irq(hw_config->irq, devc); 3462 - free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER); 3463 - free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER); 3464 - li_destroy(&devc->lith); 3465 - kfree(devc); 3466 - 3467 - return 0; 3468 - } 3469 - 3470 - /*****************************************************************************/ 3471 - /* initialization and loadable kernel module interface */ 3472 - 3473 - static struct address_info the_hw_config = { 3474 - 0xFF001000, /* lithium phys addr */ 3475 - CO_IRQ(CO_APIC_LI_AUDIO) /* irq */ 3476 - }; 3477 - 3478 - MODULE_DESCRIPTION("SGI Visual Workstation sound module"); 3479 - MODULE_AUTHOR("Bob Miller <kbob@sgi.com>"); 3480 - MODULE_LICENSE("GPL"); 3481 - 3482 - static int __init init_vwsnd(void) 3483 - { 3484 - int err; 3485 - 3486 - DBGXV("\n"); 3487 - DBGXV("sound::vwsnd::init_module()\n"); 3488 - 3489 - if (!probe_vwsnd(&the_hw_config)) 3490 - return -ENODEV; 3491 - 3492 - err = attach_vwsnd(&the_hw_config); 3493 - if (err < 0) 3494 - return err; 3495 - return 0; 3496 - } 3497 - 3498 - static void __exit cleanup_vwsnd(void) 3499 - { 3500 - DBGX("sound::vwsnd::cleanup_module()\n"); 3501 - 3502 - unload_vwsnd(&the_hw_config); 3503 - } 3504 - 3505 - module_init(init_vwsnd); 3506 - module_exit(cleanup_vwsnd);