1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Low-level ALSA driver for the ENSONIQ SoundScape
4*4882a593Smuzhiyun * Copyright (c) by Chris Rankin
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This driver was written in part using information obtained from
7*4882a593Smuzhiyun * the OSS/Free SoundScape driver, written by Hannu Savolainen.
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/init.h>
11*4882a593Smuzhiyun #include <linux/err.h>
12*4882a593Smuzhiyun #include <linux/io.h>
13*4882a593Smuzhiyun #include <linux/isa.h>
14*4882a593Smuzhiyun #include <linux/delay.h>
15*4882a593Smuzhiyun #include <linux/firmware.h>
16*4882a593Smuzhiyun #include <linux/pnp.h>
17*4882a593Smuzhiyun #include <linux/spinlock.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <asm/dma.h>
20*4882a593Smuzhiyun #include <sound/core.h>
21*4882a593Smuzhiyun #include <sound/wss.h>
22*4882a593Smuzhiyun #include <sound/mpu401.h>
23*4882a593Smuzhiyun #include <sound/initval.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun MODULE_AUTHOR("Chris Rankin");
27*4882a593Smuzhiyun MODULE_DESCRIPTION("ENSONIQ SoundScape driver");
28*4882a593Smuzhiyun MODULE_LICENSE("GPL");
29*4882a593Smuzhiyun MODULE_FIRMWARE("sndscape.co0");
30*4882a593Smuzhiyun MODULE_FIRMWARE("sndscape.co1");
31*4882a593Smuzhiyun MODULE_FIRMWARE("sndscape.co2");
32*4882a593Smuzhiyun MODULE_FIRMWARE("sndscape.co3");
33*4882a593Smuzhiyun MODULE_FIRMWARE("sndscape.co4");
34*4882a593Smuzhiyun MODULE_FIRMWARE("scope.cod");
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
37*4882a593Smuzhiyun static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
38*4882a593Smuzhiyun static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
39*4882a593Smuzhiyun static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
40*4882a593Smuzhiyun static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
41*4882a593Smuzhiyun static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
42*4882a593Smuzhiyun static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
43*4882a593Smuzhiyun static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
44*4882a593Smuzhiyun static bool joystick[SNDRV_CARDS];
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun module_param_array(index, int, NULL, 0444);
47*4882a593Smuzhiyun MODULE_PARM_DESC(index, "Index number for SoundScape soundcard");
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun module_param_array(id, charp, NULL, 0444);
50*4882a593Smuzhiyun MODULE_PARM_DESC(id, "Description for SoundScape card");
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun module_param_hw_array(port, long, ioport, NULL, 0444);
53*4882a593Smuzhiyun MODULE_PARM_DESC(port, "Port # for SoundScape driver.");
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun module_param_hw_array(wss_port, long, ioport, NULL, 0444);
56*4882a593Smuzhiyun MODULE_PARM_DESC(wss_port, "WSS Port # for SoundScape driver.");
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun module_param_hw_array(irq, int, irq, NULL, 0444);
59*4882a593Smuzhiyun MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver.");
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun module_param_hw_array(mpu_irq, int, irq, NULL, 0444);
62*4882a593Smuzhiyun MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun module_param_hw_array(dma, int, dma, NULL, 0444);
65*4882a593Smuzhiyun MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun module_param_hw_array(dma2, int, dma, NULL, 0444);
68*4882a593Smuzhiyun MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver.");
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun module_param_array(joystick, bool, NULL, 0444);
71*4882a593Smuzhiyun MODULE_PARM_DESC(joystick, "Enable gameport.");
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun #ifdef CONFIG_PNP
74*4882a593Smuzhiyun static int isa_registered;
75*4882a593Smuzhiyun static int pnp_registered;
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun static const struct pnp_card_device_id sscape_pnpids[] = {
78*4882a593Smuzhiyun { .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */
79*4882a593Smuzhiyun { .id = "ENS4081", .devs = { { "ENS1011" } } }, /* VIVO90 */
80*4882a593Smuzhiyun { .id = "" } /* end */
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
84*4882a593Smuzhiyun #endif
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #define HOST_CTRL_IO(i) ((i) + 2)
88*4882a593Smuzhiyun #define HOST_DATA_IO(i) ((i) + 3)
89*4882a593Smuzhiyun #define ODIE_ADDR_IO(i) ((i) + 4)
90*4882a593Smuzhiyun #define ODIE_DATA_IO(i) ((i) + 5)
91*4882a593Smuzhiyun #define CODEC_IO(i) ((i) + 8)
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun #define IC_ODIE 1
94*4882a593Smuzhiyun #define IC_OPUS 2
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun #define RX_READY 0x01
97*4882a593Smuzhiyun #define TX_READY 0x02
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun #define CMD_ACK 0x80
100*4882a593Smuzhiyun #define CMD_SET_MIDI_VOL 0x84
101*4882a593Smuzhiyun #define CMD_GET_MIDI_VOL 0x85
102*4882a593Smuzhiyun #define CMD_XXX_MIDI_VOL 0x86
103*4882a593Smuzhiyun #define CMD_SET_EXTMIDI 0x8a
104*4882a593Smuzhiyun #define CMD_GET_EXTMIDI 0x8b
105*4882a593Smuzhiyun #define CMD_SET_MT32 0x8c
106*4882a593Smuzhiyun #define CMD_GET_MT32 0x8d
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun enum GA_REG {
109*4882a593Smuzhiyun GA_INTSTAT_REG = 0,
110*4882a593Smuzhiyun GA_INTENA_REG,
111*4882a593Smuzhiyun GA_DMAA_REG,
112*4882a593Smuzhiyun GA_DMAB_REG,
113*4882a593Smuzhiyun GA_INTCFG_REG,
114*4882a593Smuzhiyun GA_DMACFG_REG,
115*4882a593Smuzhiyun GA_CDCFG_REG,
116*4882a593Smuzhiyun GA_SMCFGA_REG,
117*4882a593Smuzhiyun GA_SMCFGB_REG,
118*4882a593Smuzhiyun GA_HMCTL_REG
119*4882a593Smuzhiyun };
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun #define DMA_8BIT 0x80
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun enum card_type {
125*4882a593Smuzhiyun MEDIA_FX, /* Sequoia S-1000 */
126*4882a593Smuzhiyun SSCAPE, /* Sequoia S-2000 */
127*4882a593Smuzhiyun SSCAPE_PNP,
128*4882a593Smuzhiyun SSCAPE_VIVO,
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun struct soundscape {
132*4882a593Smuzhiyun spinlock_t lock;
133*4882a593Smuzhiyun unsigned io_base;
134*4882a593Smuzhiyun int ic_type;
135*4882a593Smuzhiyun enum card_type type;
136*4882a593Smuzhiyun struct resource *io_res;
137*4882a593Smuzhiyun struct resource *wss_res;
138*4882a593Smuzhiyun struct snd_wss *chip;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun unsigned char midi_vol;
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun #define INVALID_IRQ ((unsigned)-1)
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun
get_card_soundscape(struct snd_card * c)146*4882a593Smuzhiyun static inline struct soundscape *get_card_soundscape(struct snd_card *c)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun return (struct soundscape *) (c->private_data);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /*
152*4882a593Smuzhiyun * Allocates some kernel memory that we can use for DMA.
153*4882a593Smuzhiyun * I think this means that the memory has to map to
154*4882a593Smuzhiyun * contiguous pages of physical memory.
155*4882a593Smuzhiyun */
get_dmabuf(struct soundscape * s,struct snd_dma_buffer * buf,unsigned long size)156*4882a593Smuzhiyun static struct snd_dma_buffer *get_dmabuf(struct soundscape *s,
157*4882a593Smuzhiyun struct snd_dma_buffer *buf,
158*4882a593Smuzhiyun unsigned long size)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun if (buf) {
161*4882a593Smuzhiyun if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
162*4882a593Smuzhiyun s->chip->card->dev,
163*4882a593Smuzhiyun size, buf) < 0) {
164*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Failed to allocate "
165*4882a593Smuzhiyun "%lu bytes for DMA\n",
166*4882a593Smuzhiyun size);
167*4882a593Smuzhiyun return NULL;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun return buf;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /*
175*4882a593Smuzhiyun * Release the DMA-able kernel memory ...
176*4882a593Smuzhiyun */
free_dmabuf(struct snd_dma_buffer * buf)177*4882a593Smuzhiyun static void free_dmabuf(struct snd_dma_buffer *buf)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun if (buf && buf->area)
180*4882a593Smuzhiyun snd_dma_free_pages(buf);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /*
184*4882a593Smuzhiyun * This function writes to the SoundScape's control registers,
185*4882a593Smuzhiyun * but doesn't do any locking. It's up to the caller to do that.
186*4882a593Smuzhiyun * This is why this function is "unsafe" ...
187*4882a593Smuzhiyun */
sscape_write_unsafe(unsigned io_base,enum GA_REG reg,unsigned char val)188*4882a593Smuzhiyun static inline void sscape_write_unsafe(unsigned io_base, enum GA_REG reg,
189*4882a593Smuzhiyun unsigned char val)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun outb(reg, ODIE_ADDR_IO(io_base));
192*4882a593Smuzhiyun outb(val, ODIE_DATA_IO(io_base));
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun /*
196*4882a593Smuzhiyun * Write to the SoundScape's control registers, and do the
197*4882a593Smuzhiyun * necessary locking ...
198*4882a593Smuzhiyun */
sscape_write(struct soundscape * s,enum GA_REG reg,unsigned char val)199*4882a593Smuzhiyun static void sscape_write(struct soundscape *s, enum GA_REG reg,
200*4882a593Smuzhiyun unsigned char val)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun unsigned long flags;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
205*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, reg, val);
206*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /*
210*4882a593Smuzhiyun * Read from the SoundScape's control registers, but leave any
211*4882a593Smuzhiyun * locking to the caller. This is why the function is "unsafe" ...
212*4882a593Smuzhiyun */
sscape_read_unsafe(unsigned io_base,enum GA_REG reg)213*4882a593Smuzhiyun static inline unsigned char sscape_read_unsafe(unsigned io_base,
214*4882a593Smuzhiyun enum GA_REG reg)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun outb(reg, ODIE_ADDR_IO(io_base));
217*4882a593Smuzhiyun return inb(ODIE_DATA_IO(io_base));
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /*
221*4882a593Smuzhiyun * Puts the SoundScape into "host" mode, as compared to "MIDI" mode
222*4882a593Smuzhiyun */
set_host_mode_unsafe(unsigned io_base)223*4882a593Smuzhiyun static inline void set_host_mode_unsafe(unsigned io_base)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun outb(0x0, HOST_CTRL_IO(io_base));
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun /*
229*4882a593Smuzhiyun * Puts the SoundScape into "MIDI" mode, as compared to "host" mode
230*4882a593Smuzhiyun */
set_midi_mode_unsafe(unsigned io_base)231*4882a593Smuzhiyun static inline void set_midi_mode_unsafe(unsigned io_base)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun outb(0x3, HOST_CTRL_IO(io_base));
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /*
237*4882a593Smuzhiyun * Read the SoundScape's host-mode control register, but leave
238*4882a593Smuzhiyun * any locking issues to the caller ...
239*4882a593Smuzhiyun */
host_read_unsafe(unsigned io_base)240*4882a593Smuzhiyun static inline int host_read_unsafe(unsigned io_base)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun int data = -1;
243*4882a593Smuzhiyun if ((inb(HOST_CTRL_IO(io_base)) & RX_READY) != 0)
244*4882a593Smuzhiyun data = inb(HOST_DATA_IO(io_base));
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun return data;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun /*
250*4882a593Smuzhiyun * Read the SoundScape's host-mode control register, performing
251*4882a593Smuzhiyun * a limited amount of busy-waiting if the register isn't ready.
252*4882a593Smuzhiyun * Also leaves all locking-issues to the caller ...
253*4882a593Smuzhiyun */
host_read_ctrl_unsafe(unsigned io_base,unsigned timeout)254*4882a593Smuzhiyun static int host_read_ctrl_unsafe(unsigned io_base, unsigned timeout)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun int data;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun while (((data = host_read_unsafe(io_base)) < 0) && (timeout != 0)) {
259*4882a593Smuzhiyun udelay(100);
260*4882a593Smuzhiyun --timeout;
261*4882a593Smuzhiyun } /* while */
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun return data;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun /*
267*4882a593Smuzhiyun * Write to the SoundScape's host-mode control registers, but
268*4882a593Smuzhiyun * leave any locking issues to the caller ...
269*4882a593Smuzhiyun */
host_write_unsafe(unsigned io_base,unsigned char data)270*4882a593Smuzhiyun static inline int host_write_unsafe(unsigned io_base, unsigned char data)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun if ((inb(HOST_CTRL_IO(io_base)) & TX_READY) != 0) {
273*4882a593Smuzhiyun outb(data, HOST_DATA_IO(io_base));
274*4882a593Smuzhiyun return 1;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun return 0;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun /*
281*4882a593Smuzhiyun * Write to the SoundScape's host-mode control registers, performing
282*4882a593Smuzhiyun * a limited amount of busy-waiting if the register isn't ready.
283*4882a593Smuzhiyun * Also leaves all locking-issues to the caller ...
284*4882a593Smuzhiyun */
host_write_ctrl_unsafe(unsigned io_base,unsigned char data,unsigned timeout)285*4882a593Smuzhiyun static int host_write_ctrl_unsafe(unsigned io_base, unsigned char data,
286*4882a593Smuzhiyun unsigned timeout)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun int err;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun while (!(err = host_write_unsafe(io_base, data)) && (timeout != 0)) {
291*4882a593Smuzhiyun udelay(100);
292*4882a593Smuzhiyun --timeout;
293*4882a593Smuzhiyun } /* while */
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun return err;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun /*
300*4882a593Smuzhiyun * Check that the MIDI subsystem is operational. If it isn't,
301*4882a593Smuzhiyun * then we will hang the computer if we try to use it ...
302*4882a593Smuzhiyun *
303*4882a593Smuzhiyun * NOTE: This check is based upon observation, not documentation.
304*4882a593Smuzhiyun */
verify_mpu401(const struct snd_mpu401 * mpu)305*4882a593Smuzhiyun static inline int verify_mpu401(const struct snd_mpu401 *mpu)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun return ((inb(MPU401C(mpu)) & 0xc0) == 0x80);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /*
311*4882a593Smuzhiyun * This is apparently the standard way to initialise an MPU-401
312*4882a593Smuzhiyun */
initialise_mpu401(const struct snd_mpu401 * mpu)313*4882a593Smuzhiyun static inline void initialise_mpu401(const struct snd_mpu401 *mpu)
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun outb(0, MPU401D(mpu));
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /*
319*4882a593Smuzhiyun * Tell the SoundScape to activate the AD1845 chip (I think).
320*4882a593Smuzhiyun * The AD1845 detection fails if we *don't* do this, so I
321*4882a593Smuzhiyun * think that this is a good idea ...
322*4882a593Smuzhiyun */
activate_ad1845_unsafe(unsigned io_base)323*4882a593Smuzhiyun static void activate_ad1845_unsafe(unsigned io_base)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun unsigned char val = sscape_read_unsafe(io_base, GA_HMCTL_REG);
326*4882a593Smuzhiyun sscape_write_unsafe(io_base, GA_HMCTL_REG, (val & 0xcf) | 0x10);
327*4882a593Smuzhiyun sscape_write_unsafe(io_base, GA_CDCFG_REG, 0x80);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /*
331*4882a593Smuzhiyun * Do the necessary ALSA-level cleanup to deallocate our driver ...
332*4882a593Smuzhiyun */
soundscape_free(struct snd_card * c)333*4882a593Smuzhiyun static void soundscape_free(struct snd_card *c)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun struct soundscape *sscape = get_card_soundscape(c);
336*4882a593Smuzhiyun release_and_free_resource(sscape->io_res);
337*4882a593Smuzhiyun release_and_free_resource(sscape->wss_res);
338*4882a593Smuzhiyun free_dma(sscape->chip->dma1);
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun /*
342*4882a593Smuzhiyun * Tell the SoundScape to begin a DMA transfer using the given channel.
343*4882a593Smuzhiyun * All locking issues are left to the caller.
344*4882a593Smuzhiyun */
sscape_start_dma_unsafe(unsigned io_base,enum GA_REG reg)345*4882a593Smuzhiyun static void sscape_start_dma_unsafe(unsigned io_base, enum GA_REG reg)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun sscape_write_unsafe(io_base, reg,
348*4882a593Smuzhiyun sscape_read_unsafe(io_base, reg) | 0x01);
349*4882a593Smuzhiyun sscape_write_unsafe(io_base, reg,
350*4882a593Smuzhiyun sscape_read_unsafe(io_base, reg) & 0xfe);
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun /*
354*4882a593Smuzhiyun * Wait for a DMA transfer to complete. This is a "limited busy-wait",
355*4882a593Smuzhiyun * and all locking issues are left to the caller.
356*4882a593Smuzhiyun */
sscape_wait_dma_unsafe(unsigned io_base,enum GA_REG reg,unsigned timeout)357*4882a593Smuzhiyun static int sscape_wait_dma_unsafe(unsigned io_base, enum GA_REG reg,
358*4882a593Smuzhiyun unsigned timeout)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun while (!(sscape_read_unsafe(io_base, reg) & 0x01) && (timeout != 0)) {
361*4882a593Smuzhiyun udelay(100);
362*4882a593Smuzhiyun --timeout;
363*4882a593Smuzhiyun } /* while */
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun return sscape_read_unsafe(io_base, reg) & 0x01;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /*
369*4882a593Smuzhiyun * Wait for the On-Board Processor to return its start-up
370*4882a593Smuzhiyun * acknowledgement sequence. This wait is too long for
371*4882a593Smuzhiyun * us to perform "busy-waiting", and so we must sleep.
372*4882a593Smuzhiyun * This in turn means that we must not be holding any
373*4882a593Smuzhiyun * spinlocks when we call this function.
374*4882a593Smuzhiyun */
obp_startup_ack(struct soundscape * s,unsigned timeout)375*4882a593Smuzhiyun static int obp_startup_ack(struct soundscape *s, unsigned timeout)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun unsigned long end_time = jiffies + msecs_to_jiffies(timeout);
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun do {
380*4882a593Smuzhiyun unsigned long flags;
381*4882a593Smuzhiyun int x;
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
384*4882a593Smuzhiyun x = host_read_unsafe(s->io_base);
385*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
386*4882a593Smuzhiyun if (x == 0xfe || x == 0xff)
387*4882a593Smuzhiyun return 1;
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun msleep(10);
390*4882a593Smuzhiyun } while (time_before(jiffies, end_time));
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /*
396*4882a593Smuzhiyun * Wait for the host to return its start-up acknowledgement
397*4882a593Smuzhiyun * sequence. This wait is too long for us to perform
398*4882a593Smuzhiyun * "busy-waiting", and so we must sleep. This in turn means
399*4882a593Smuzhiyun * that we must not be holding any spinlocks when we call
400*4882a593Smuzhiyun * this function.
401*4882a593Smuzhiyun */
host_startup_ack(struct soundscape * s,unsigned timeout)402*4882a593Smuzhiyun static int host_startup_ack(struct soundscape *s, unsigned timeout)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun unsigned long end_time = jiffies + msecs_to_jiffies(timeout);
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun do {
407*4882a593Smuzhiyun unsigned long flags;
408*4882a593Smuzhiyun int x;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
411*4882a593Smuzhiyun x = host_read_unsafe(s->io_base);
412*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
413*4882a593Smuzhiyun if (x == 0xfe)
414*4882a593Smuzhiyun return 1;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun msleep(10);
417*4882a593Smuzhiyun } while (time_before(jiffies, end_time));
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun return 0;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun /*
423*4882a593Smuzhiyun * Upload a byte-stream into the SoundScape using DMA channel A.
424*4882a593Smuzhiyun */
upload_dma_data(struct soundscape * s,const unsigned char * data,size_t size)425*4882a593Smuzhiyun static int upload_dma_data(struct soundscape *s, const unsigned char *data,
426*4882a593Smuzhiyun size_t size)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun unsigned long flags;
429*4882a593Smuzhiyun struct snd_dma_buffer dma;
430*4882a593Smuzhiyun int ret;
431*4882a593Smuzhiyun unsigned char val;
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun if (!get_dmabuf(s, &dma, PAGE_ALIGN(32 * 1024)))
434*4882a593Smuzhiyun return -ENOMEM;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun /*
439*4882a593Smuzhiyun * Reset the board ...
440*4882a593Smuzhiyun */
441*4882a593Smuzhiyun val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
442*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val & 0x3f);
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun /*
445*4882a593Smuzhiyun * Enable the DMA channels and configure them ...
446*4882a593Smuzhiyun */
447*4882a593Smuzhiyun val = (s->chip->dma1 << 4) | DMA_8BIT;
448*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_DMAA_REG, val);
449*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_DMAB_REG, 0x20);
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun /*
452*4882a593Smuzhiyun * Take the board out of reset ...
453*4882a593Smuzhiyun */
454*4882a593Smuzhiyun val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
455*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x80);
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun /*
458*4882a593Smuzhiyun * Upload the firmware to the SoundScape
459*4882a593Smuzhiyun * board through the DMA channel ...
460*4882a593Smuzhiyun */
461*4882a593Smuzhiyun while (size != 0) {
462*4882a593Smuzhiyun unsigned long len;
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun len = min(size, dma.bytes);
465*4882a593Smuzhiyun memcpy(dma.area, data, len);
466*4882a593Smuzhiyun data += len;
467*4882a593Smuzhiyun size -= len;
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun snd_dma_program(s->chip->dma1, dma.addr, len, DMA_MODE_WRITE);
470*4882a593Smuzhiyun sscape_start_dma_unsafe(s->io_base, GA_DMAA_REG);
471*4882a593Smuzhiyun if (!sscape_wait_dma_unsafe(s->io_base, GA_DMAA_REG, 5000)) {
472*4882a593Smuzhiyun /*
473*4882a593Smuzhiyun * Don't forget to release this spinlock we're holding
474*4882a593Smuzhiyun */
475*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun snd_printk(KERN_ERR
478*4882a593Smuzhiyun "sscape: DMA upload has timed out\n");
479*4882a593Smuzhiyun ret = -EAGAIN;
480*4882a593Smuzhiyun goto _release_dma;
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun } /* while */
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun set_host_mode_unsafe(s->io_base);
485*4882a593Smuzhiyun outb(0x0, s->io_base);
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun /*
488*4882a593Smuzhiyun * Boot the board ... (I think)
489*4882a593Smuzhiyun */
490*4882a593Smuzhiyun val = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
491*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_HMCTL_REG, val | 0x40);
492*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun /*
495*4882a593Smuzhiyun * If all has gone well, then the board should acknowledge
496*4882a593Smuzhiyun * the new upload and tell us that it has rebooted OK. We
497*4882a593Smuzhiyun * give it 5 seconds (max) ...
498*4882a593Smuzhiyun */
499*4882a593Smuzhiyun ret = 0;
500*4882a593Smuzhiyun if (!obp_startup_ack(s, 5000)) {
501*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: No response "
502*4882a593Smuzhiyun "from on-board processor after upload\n");
503*4882a593Smuzhiyun ret = -EAGAIN;
504*4882a593Smuzhiyun } else if (!host_startup_ack(s, 5000)) {
505*4882a593Smuzhiyun snd_printk(KERN_ERR
506*4882a593Smuzhiyun "sscape: SoundScape failed to initialise\n");
507*4882a593Smuzhiyun ret = -EAGAIN;
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun _release_dma:
511*4882a593Smuzhiyun /*
512*4882a593Smuzhiyun * NOTE!!! We are NOT holding any spinlocks at this point !!!
513*4882a593Smuzhiyun */
514*4882a593Smuzhiyun sscape_write(s, GA_DMAA_REG, (s->ic_type == IC_OPUS ? 0x40 : 0x70));
515*4882a593Smuzhiyun free_dmabuf(&dma);
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun return ret;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun /*
521*4882a593Smuzhiyun * Upload the bootblock(?) into the SoundScape. The only
522*4882a593Smuzhiyun * purpose of this block of code seems to be to tell
523*4882a593Smuzhiyun * us which version of the microcode we should be using.
524*4882a593Smuzhiyun */
sscape_upload_bootblock(struct snd_card * card)525*4882a593Smuzhiyun static int sscape_upload_bootblock(struct snd_card *card)
526*4882a593Smuzhiyun {
527*4882a593Smuzhiyun struct soundscape *sscape = get_card_soundscape(card);
528*4882a593Smuzhiyun unsigned long flags;
529*4882a593Smuzhiyun const struct firmware *init_fw = NULL;
530*4882a593Smuzhiyun int data = 0;
531*4882a593Smuzhiyun int ret;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun ret = request_firmware(&init_fw, "scope.cod", card->dev);
534*4882a593Smuzhiyun if (ret < 0) {
535*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Error loading scope.cod");
536*4882a593Smuzhiyun return ret;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun ret = upload_dma_data(sscape, init_fw->data, init_fw->size);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun release_firmware(init_fw);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun spin_lock_irqsave(&sscape->lock, flags);
543*4882a593Smuzhiyun if (ret == 0)
544*4882a593Smuzhiyun data = host_read_ctrl_unsafe(sscape->io_base, 100);
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun if (data & 0x10)
547*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2f);
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun spin_unlock_irqrestore(&sscape->lock, flags);
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun data &= 0xf;
552*4882a593Smuzhiyun if (ret == 0 && data > 7) {
553*4882a593Smuzhiyun snd_printk(KERN_ERR
554*4882a593Smuzhiyun "sscape: timeout reading firmware version\n");
555*4882a593Smuzhiyun ret = -EAGAIN;
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun return (ret == 0) ? data : ret;
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun /*
562*4882a593Smuzhiyun * Upload the microcode into the SoundScape.
563*4882a593Smuzhiyun */
sscape_upload_microcode(struct snd_card * card,int version)564*4882a593Smuzhiyun static int sscape_upload_microcode(struct snd_card *card, int version)
565*4882a593Smuzhiyun {
566*4882a593Smuzhiyun struct soundscape *sscape = get_card_soundscape(card);
567*4882a593Smuzhiyun const struct firmware *init_fw = NULL;
568*4882a593Smuzhiyun char name[14];
569*4882a593Smuzhiyun int err;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun snprintf(name, sizeof(name), "sndscape.co%d", version);
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun err = request_firmware(&init_fw, name, card->dev);
574*4882a593Smuzhiyun if (err < 0) {
575*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Error loading sndscape.co%d",
576*4882a593Smuzhiyun version);
577*4882a593Smuzhiyun return err;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun err = upload_dma_data(sscape, init_fw->data, init_fw->size);
580*4882a593Smuzhiyun if (err == 0)
581*4882a593Smuzhiyun snd_printk(KERN_INFO "sscape: MIDI firmware loaded %zu KBs\n",
582*4882a593Smuzhiyun init_fw->size >> 10);
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun release_firmware(init_fw);
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun return err;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun /*
590*4882a593Smuzhiyun * Mixer control for the SoundScape's MIDI device.
591*4882a593Smuzhiyun */
sscape_midi_info(struct snd_kcontrol * ctl,struct snd_ctl_elem_info * uinfo)592*4882a593Smuzhiyun static int sscape_midi_info(struct snd_kcontrol *ctl,
593*4882a593Smuzhiyun struct snd_ctl_elem_info *uinfo)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
596*4882a593Smuzhiyun uinfo->count = 1;
597*4882a593Smuzhiyun uinfo->value.integer.min = 0;
598*4882a593Smuzhiyun uinfo->value.integer.max = 127;
599*4882a593Smuzhiyun return 0;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun
sscape_midi_get(struct snd_kcontrol * kctl,struct snd_ctl_elem_value * uctl)602*4882a593Smuzhiyun static int sscape_midi_get(struct snd_kcontrol *kctl,
603*4882a593Smuzhiyun struct snd_ctl_elem_value *uctl)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun struct snd_wss *chip = snd_kcontrol_chip(kctl);
606*4882a593Smuzhiyun struct snd_card *card = chip->card;
607*4882a593Smuzhiyun register struct soundscape *s = get_card_soundscape(card);
608*4882a593Smuzhiyun unsigned long flags;
609*4882a593Smuzhiyun
610*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
611*4882a593Smuzhiyun uctl->value.integer.value[0] = s->midi_vol;
612*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
613*4882a593Smuzhiyun return 0;
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun
sscape_midi_put(struct snd_kcontrol * kctl,struct snd_ctl_elem_value * uctl)616*4882a593Smuzhiyun static int sscape_midi_put(struct snd_kcontrol *kctl,
617*4882a593Smuzhiyun struct snd_ctl_elem_value *uctl)
618*4882a593Smuzhiyun {
619*4882a593Smuzhiyun struct snd_wss *chip = snd_kcontrol_chip(kctl);
620*4882a593Smuzhiyun struct snd_card *card = chip->card;
621*4882a593Smuzhiyun struct soundscape *s = get_card_soundscape(card);
622*4882a593Smuzhiyun unsigned long flags;
623*4882a593Smuzhiyun int change;
624*4882a593Smuzhiyun unsigned char new_val;
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun new_val = uctl->value.integer.value[0] & 127;
629*4882a593Smuzhiyun /*
630*4882a593Smuzhiyun * We need to put the board into HOST mode before we
631*4882a593Smuzhiyun * can send any volume-changing HOST commands ...
632*4882a593Smuzhiyun */
633*4882a593Smuzhiyun set_host_mode_unsafe(s->io_base);
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun /*
636*4882a593Smuzhiyun * To successfully change the MIDI volume setting, you seem to
637*4882a593Smuzhiyun * have to write a volume command, write the new volume value,
638*4882a593Smuzhiyun * and then perform another volume-related command. Perhaps the
639*4882a593Smuzhiyun * first command is an "open" and the second command is a "close"?
640*4882a593Smuzhiyun */
641*4882a593Smuzhiyun if (s->midi_vol == new_val) {
642*4882a593Smuzhiyun change = 0;
643*4882a593Smuzhiyun goto __skip_change;
644*4882a593Smuzhiyun }
645*4882a593Smuzhiyun change = host_write_ctrl_unsafe(s->io_base, CMD_SET_MIDI_VOL, 100)
646*4882a593Smuzhiyun && host_write_ctrl_unsafe(s->io_base, new_val, 100)
647*4882a593Smuzhiyun && host_write_ctrl_unsafe(s->io_base, CMD_XXX_MIDI_VOL, 100)
648*4882a593Smuzhiyun && host_write_ctrl_unsafe(s->io_base, new_val, 100);
649*4882a593Smuzhiyun s->midi_vol = new_val;
650*4882a593Smuzhiyun __skip_change:
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun /*
653*4882a593Smuzhiyun * Take the board out of HOST mode and back into MIDI mode ...
654*4882a593Smuzhiyun */
655*4882a593Smuzhiyun set_midi_mode_unsafe(s->io_base);
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
658*4882a593Smuzhiyun return change;
659*4882a593Smuzhiyun }
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun static const struct snd_kcontrol_new midi_mixer_ctl = {
662*4882a593Smuzhiyun .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
663*4882a593Smuzhiyun .name = "MIDI",
664*4882a593Smuzhiyun .info = sscape_midi_info,
665*4882a593Smuzhiyun .get = sscape_midi_get,
666*4882a593Smuzhiyun .put = sscape_midi_put
667*4882a593Smuzhiyun };
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun /*
670*4882a593Smuzhiyun * The SoundScape can use two IRQs from a possible set of four.
671*4882a593Smuzhiyun * These IRQs are encoded as bit patterns so that they can be
672*4882a593Smuzhiyun * written to the control registers.
673*4882a593Smuzhiyun */
get_irq_config(int sscape_type,int irq)674*4882a593Smuzhiyun static unsigned get_irq_config(int sscape_type, int irq)
675*4882a593Smuzhiyun {
676*4882a593Smuzhiyun static const int valid_irq[] = { 9, 5, 7, 10 };
677*4882a593Smuzhiyun static const int old_irq[] = { 9, 7, 5, 15 };
678*4882a593Smuzhiyun unsigned cfg;
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun if (sscape_type == MEDIA_FX) {
681*4882a593Smuzhiyun for (cfg = 0; cfg < ARRAY_SIZE(old_irq); ++cfg)
682*4882a593Smuzhiyun if (irq == old_irq[cfg])
683*4882a593Smuzhiyun return cfg;
684*4882a593Smuzhiyun } else {
685*4882a593Smuzhiyun for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg)
686*4882a593Smuzhiyun if (irq == valid_irq[cfg])
687*4882a593Smuzhiyun return cfg;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun return INVALID_IRQ;
691*4882a593Smuzhiyun }
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun /*
694*4882a593Smuzhiyun * Perform certain arcane port-checks to see whether there
695*4882a593Smuzhiyun * is a SoundScape board lurking behind the given ports.
696*4882a593Smuzhiyun */
detect_sscape(struct soundscape * s,long wss_io)697*4882a593Smuzhiyun static int detect_sscape(struct soundscape *s, long wss_io)
698*4882a593Smuzhiyun {
699*4882a593Smuzhiyun unsigned long flags;
700*4882a593Smuzhiyun unsigned d;
701*4882a593Smuzhiyun int retval = 0;
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun /*
706*4882a593Smuzhiyun * The following code is lifted from the original OSS driver,
707*4882a593Smuzhiyun * and as I don't have a datasheet I cannot really comment
708*4882a593Smuzhiyun * on what it is doing...
709*4882a593Smuzhiyun */
710*4882a593Smuzhiyun if ((inb(HOST_CTRL_IO(s->io_base)) & 0x78) != 0)
711*4882a593Smuzhiyun goto _done;
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun d = inb(ODIE_ADDR_IO(s->io_base)) & 0xf0;
714*4882a593Smuzhiyun if ((d & 0x80) != 0)
715*4882a593Smuzhiyun goto _done;
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun if (d == 0)
718*4882a593Smuzhiyun s->ic_type = IC_ODIE;
719*4882a593Smuzhiyun else if ((d & 0x60) != 0)
720*4882a593Smuzhiyun s->ic_type = IC_OPUS;
721*4882a593Smuzhiyun else
722*4882a593Smuzhiyun goto _done;
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun outb(0xfa, ODIE_ADDR_IO(s->io_base));
725*4882a593Smuzhiyun if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0a)
726*4882a593Smuzhiyun goto _done;
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun outb(0xfe, ODIE_ADDR_IO(s->io_base));
729*4882a593Smuzhiyun if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0e)
730*4882a593Smuzhiyun goto _done;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun outb(0xfe, ODIE_ADDR_IO(s->io_base));
733*4882a593Smuzhiyun d = inb(ODIE_DATA_IO(s->io_base));
734*4882a593Smuzhiyun if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e)
735*4882a593Smuzhiyun goto _done;
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun if (s->ic_type == IC_OPUS)
738*4882a593Smuzhiyun activate_ad1845_unsafe(s->io_base);
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun if (s->type == SSCAPE_VIVO)
741*4882a593Smuzhiyun wss_io += 4;
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
744*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun /* wait for WSS codec */
747*4882a593Smuzhiyun for (d = 0; d < 500; d++) {
748*4882a593Smuzhiyun if ((inb(wss_io) & 0x80) == 0)
749*4882a593Smuzhiyun break;
750*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
751*4882a593Smuzhiyun msleep(1);
752*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun
755*4882a593Smuzhiyun if ((inb(wss_io) & 0x80) != 0)
756*4882a593Smuzhiyun goto _done;
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun if (inb(wss_io + 2) == 0xff)
759*4882a593Smuzhiyun goto _done;
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
762*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d);
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun if ((inb(wss_io) & 0x80) != 0)
765*4882a593Smuzhiyun s->type = MEDIA_FX;
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG);
768*4882a593Smuzhiyun sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
769*4882a593Smuzhiyun /* wait for WSS codec */
770*4882a593Smuzhiyun for (d = 0; d < 500; d++) {
771*4882a593Smuzhiyun if ((inb(wss_io) & 0x80) == 0)
772*4882a593Smuzhiyun break;
773*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
774*4882a593Smuzhiyun msleep(1);
775*4882a593Smuzhiyun spin_lock_irqsave(&s->lock, flags);
776*4882a593Smuzhiyun }
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun /*
779*4882a593Smuzhiyun * SoundScape successfully detected!
780*4882a593Smuzhiyun */
781*4882a593Smuzhiyun retval = 1;
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun _done:
784*4882a593Smuzhiyun spin_unlock_irqrestore(&s->lock, flags);
785*4882a593Smuzhiyun return retval;
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun /*
789*4882a593Smuzhiyun * ALSA callback function, called when attempting to open the MIDI device.
790*4882a593Smuzhiyun * Check that the MIDI firmware has been loaded, because we don't want
791*4882a593Smuzhiyun * to crash the machine. Also check that someone isn't using the hardware
792*4882a593Smuzhiyun * IOCTL device.
793*4882a593Smuzhiyun */
mpu401_open(struct snd_mpu401 * mpu)794*4882a593Smuzhiyun static int mpu401_open(struct snd_mpu401 *mpu)
795*4882a593Smuzhiyun {
796*4882a593Smuzhiyun if (!verify_mpu401(mpu)) {
797*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: MIDI disabled, "
798*4882a593Smuzhiyun "please load firmware\n");
799*4882a593Smuzhiyun return -ENODEV;
800*4882a593Smuzhiyun }
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun return 0;
803*4882a593Smuzhiyun }
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun /*
806*4882a593Smuzhiyun * Initialise an MPU-401 subdevice for MIDI support on the SoundScape.
807*4882a593Smuzhiyun */
create_mpu401(struct snd_card * card,int devnum,unsigned long port,int irq)808*4882a593Smuzhiyun static int create_mpu401(struct snd_card *card, int devnum,
809*4882a593Smuzhiyun unsigned long port, int irq)
810*4882a593Smuzhiyun {
811*4882a593Smuzhiyun struct soundscape *sscape = get_card_soundscape(card);
812*4882a593Smuzhiyun struct snd_rawmidi *rawmidi;
813*4882a593Smuzhiyun int err;
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port,
816*4882a593Smuzhiyun MPU401_INFO_INTEGRATED, irq, &rawmidi);
817*4882a593Smuzhiyun if (err == 0) {
818*4882a593Smuzhiyun struct snd_mpu401 *mpu = rawmidi->private_data;
819*4882a593Smuzhiyun mpu->open_input = mpu401_open;
820*4882a593Smuzhiyun mpu->open_output = mpu401_open;
821*4882a593Smuzhiyun mpu->private_data = sscape;
822*4882a593Smuzhiyun
823*4882a593Smuzhiyun initialise_mpu401(mpu);
824*4882a593Smuzhiyun }
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun return err;
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun /*
831*4882a593Smuzhiyun * Create an AD1845 PCM subdevice on the SoundScape. The AD1845
832*4882a593Smuzhiyun * is very much like a CS4231, with a few extra bits. We will
833*4882a593Smuzhiyun * try to support at least some of the extra bits by overriding
834*4882a593Smuzhiyun * some of the CS4231 callback.
835*4882a593Smuzhiyun */
create_ad1845(struct snd_card * card,unsigned port,int irq,int dma1,int dma2)836*4882a593Smuzhiyun static int create_ad1845(struct snd_card *card, unsigned port,
837*4882a593Smuzhiyun int irq, int dma1, int dma2)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun register struct soundscape *sscape = get_card_soundscape(card);
840*4882a593Smuzhiyun struct snd_wss *chip;
841*4882a593Smuzhiyun int err;
842*4882a593Smuzhiyun int codec_type = WSS_HW_DETECT;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun switch (sscape->type) {
845*4882a593Smuzhiyun case MEDIA_FX:
846*4882a593Smuzhiyun case SSCAPE:
847*4882a593Smuzhiyun /*
848*4882a593Smuzhiyun * There are some freak examples of early Soundscape cards
849*4882a593Smuzhiyun * with CS4231 instead of AD1848/CS4248. Unfortunately, the
850*4882a593Smuzhiyun * CS4231 works only in CS4248 compatibility mode on
851*4882a593Smuzhiyun * these cards so force it.
852*4882a593Smuzhiyun */
853*4882a593Smuzhiyun if (sscape->ic_type != IC_OPUS)
854*4882a593Smuzhiyun codec_type = WSS_HW_AD1848;
855*4882a593Smuzhiyun break;
856*4882a593Smuzhiyun
857*4882a593Smuzhiyun case SSCAPE_VIVO:
858*4882a593Smuzhiyun port += 4;
859*4882a593Smuzhiyun break;
860*4882a593Smuzhiyun default:
861*4882a593Smuzhiyun break;
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun err = snd_wss_create(card, port, -1, irq, dma1, dma2,
865*4882a593Smuzhiyun codec_type, WSS_HWSHARE_DMA1, &chip);
866*4882a593Smuzhiyun if (!err) {
867*4882a593Smuzhiyun unsigned long flags;
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun if (sscape->type != SSCAPE_VIVO) {
870*4882a593Smuzhiyun /*
871*4882a593Smuzhiyun * The input clock frequency on the SoundScape must
872*4882a593Smuzhiyun * be 14.31818 MHz, because we must set this register
873*4882a593Smuzhiyun * to get the playback to sound correct ...
874*4882a593Smuzhiyun */
875*4882a593Smuzhiyun snd_wss_mce_up(chip);
876*4882a593Smuzhiyun spin_lock_irqsave(&chip->reg_lock, flags);
877*4882a593Smuzhiyun snd_wss_out(chip, AD1845_CLOCK, 0x20);
878*4882a593Smuzhiyun spin_unlock_irqrestore(&chip->reg_lock, flags);
879*4882a593Smuzhiyun snd_wss_mce_down(chip);
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun }
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun err = snd_wss_pcm(chip, 0);
884*4882a593Smuzhiyun if (err < 0) {
885*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: No PCM device "
886*4882a593Smuzhiyun "for AD1845 chip\n");
887*4882a593Smuzhiyun goto _error;
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun err = snd_wss_mixer(chip);
891*4882a593Smuzhiyun if (err < 0) {
892*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: No mixer device "
893*4882a593Smuzhiyun "for AD1845 chip\n");
894*4882a593Smuzhiyun goto _error;
895*4882a593Smuzhiyun }
896*4882a593Smuzhiyun if (chip->hardware != WSS_HW_AD1848) {
897*4882a593Smuzhiyun err = snd_wss_timer(chip, 0);
898*4882a593Smuzhiyun if (err < 0) {
899*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: No timer device "
900*4882a593Smuzhiyun "for AD1845 chip\n");
901*4882a593Smuzhiyun goto _error;
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun }
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun if (sscape->type != SSCAPE_VIVO) {
906*4882a593Smuzhiyun err = snd_ctl_add(card,
907*4882a593Smuzhiyun snd_ctl_new1(&midi_mixer_ctl, chip));
908*4882a593Smuzhiyun if (err < 0) {
909*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Could not create "
910*4882a593Smuzhiyun "MIDI mixer control\n");
911*4882a593Smuzhiyun goto _error;
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun sscape->chip = chip;
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun
918*4882a593Smuzhiyun _error:
919*4882a593Smuzhiyun return err;
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun /*
924*4882a593Smuzhiyun * Create an ALSA soundcard entry for the SoundScape, using
925*4882a593Smuzhiyun * the given list of port, IRQ and DMA resources.
926*4882a593Smuzhiyun */
create_sscape(int dev,struct snd_card * card)927*4882a593Smuzhiyun static int create_sscape(int dev, struct snd_card *card)
928*4882a593Smuzhiyun {
929*4882a593Smuzhiyun struct soundscape *sscape = get_card_soundscape(card);
930*4882a593Smuzhiyun unsigned dma_cfg;
931*4882a593Smuzhiyun unsigned irq_cfg;
932*4882a593Smuzhiyun unsigned mpu_irq_cfg;
933*4882a593Smuzhiyun struct resource *io_res;
934*4882a593Smuzhiyun struct resource *wss_res;
935*4882a593Smuzhiyun unsigned long flags;
936*4882a593Smuzhiyun int err;
937*4882a593Smuzhiyun int val;
938*4882a593Smuzhiyun const char *name;
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun /*
941*4882a593Smuzhiyun * Grab IO ports that we will need to probe so that we
942*4882a593Smuzhiyun * can detect and control this hardware ...
943*4882a593Smuzhiyun */
944*4882a593Smuzhiyun io_res = request_region(port[dev], 8, "SoundScape");
945*4882a593Smuzhiyun if (!io_res) {
946*4882a593Smuzhiyun snd_printk(KERN_ERR
947*4882a593Smuzhiyun "sscape: can't grab port 0x%lx\n", port[dev]);
948*4882a593Smuzhiyun return -EBUSY;
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun wss_res = NULL;
951*4882a593Smuzhiyun if (sscape->type == SSCAPE_VIVO) {
952*4882a593Smuzhiyun wss_res = request_region(wss_port[dev], 4, "SoundScape");
953*4882a593Smuzhiyun if (!wss_res) {
954*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: can't grab port 0x%lx\n",
955*4882a593Smuzhiyun wss_port[dev]);
956*4882a593Smuzhiyun err = -EBUSY;
957*4882a593Smuzhiyun goto _release_region;
958*4882a593Smuzhiyun }
959*4882a593Smuzhiyun }
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun /*
962*4882a593Smuzhiyun * Grab one DMA channel ...
963*4882a593Smuzhiyun */
964*4882a593Smuzhiyun err = request_dma(dma[dev], "SoundScape");
965*4882a593Smuzhiyun if (err < 0) {
966*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]);
967*4882a593Smuzhiyun goto _release_region;
968*4882a593Smuzhiyun }
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun spin_lock_init(&sscape->lock);
971*4882a593Smuzhiyun sscape->io_res = io_res;
972*4882a593Smuzhiyun sscape->wss_res = wss_res;
973*4882a593Smuzhiyun sscape->io_base = port[dev];
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun if (!detect_sscape(sscape, wss_port[dev])) {
976*4882a593Smuzhiyun printk(KERN_ERR "sscape: hardware not detected at 0x%x\n",
977*4882a593Smuzhiyun sscape->io_base);
978*4882a593Smuzhiyun err = -ENODEV;
979*4882a593Smuzhiyun goto _release_dma;
980*4882a593Smuzhiyun }
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun switch (sscape->type) {
983*4882a593Smuzhiyun case MEDIA_FX:
984*4882a593Smuzhiyun name = "MediaFX/SoundFX";
985*4882a593Smuzhiyun break;
986*4882a593Smuzhiyun case SSCAPE:
987*4882a593Smuzhiyun name = "Soundscape";
988*4882a593Smuzhiyun break;
989*4882a593Smuzhiyun case SSCAPE_PNP:
990*4882a593Smuzhiyun name = "Soundscape PnP";
991*4882a593Smuzhiyun break;
992*4882a593Smuzhiyun case SSCAPE_VIVO:
993*4882a593Smuzhiyun name = "Soundscape VIVO";
994*4882a593Smuzhiyun break;
995*4882a593Smuzhiyun default:
996*4882a593Smuzhiyun name = "unknown Soundscape";
997*4882a593Smuzhiyun break;
998*4882a593Smuzhiyun }
999*4882a593Smuzhiyun
1000*4882a593Smuzhiyun printk(KERN_INFO "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n",
1001*4882a593Smuzhiyun name, sscape->io_base, irq[dev], dma[dev]);
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun /*
1004*4882a593Smuzhiyun * Check that the user didn't pass us garbage data ...
1005*4882a593Smuzhiyun */
1006*4882a593Smuzhiyun irq_cfg = get_irq_config(sscape->type, irq[dev]);
1007*4882a593Smuzhiyun if (irq_cfg == INVALID_IRQ) {
1008*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
1009*4882a593Smuzhiyun err = -ENXIO;
1010*4882a593Smuzhiyun goto _release_dma;
1011*4882a593Smuzhiyun }
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]);
1014*4882a593Smuzhiyun if (mpu_irq_cfg == INVALID_IRQ) {
1015*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
1016*4882a593Smuzhiyun err = -ENXIO;
1017*4882a593Smuzhiyun goto _release_dma;
1018*4882a593Smuzhiyun }
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun /*
1021*4882a593Smuzhiyun * Tell the on-board devices where their resources are (I think -
1022*4882a593Smuzhiyun * I can't be sure without a datasheet ... So many magic values!)
1023*4882a593Smuzhiyun */
1024*4882a593Smuzhiyun spin_lock_irqsave(&sscape->lock, flags);
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
1027*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun /*
1030*4882a593Smuzhiyun * Enable and configure the DMA channels ...
1031*4882a593Smuzhiyun */
1032*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50);
1033*4882a593Smuzhiyun dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70);
1034*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
1035*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun mpu_irq_cfg |= mpu_irq_cfg << 2;
1038*4882a593Smuzhiyun val = sscape_read_unsafe(sscape->io_base, GA_HMCTL_REG) & 0xF7;
1039*4882a593Smuzhiyun if (joystick[dev])
1040*4882a593Smuzhiyun val |= 8;
1041*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_HMCTL_REG, val | 0x10);
1042*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg);
1043*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base,
1044*4882a593Smuzhiyun GA_CDCFG_REG, 0x09 | DMA_8BIT
1045*4882a593Smuzhiyun | (dma[dev] << 4) | (irq_cfg << 1));
1046*4882a593Smuzhiyun /*
1047*4882a593Smuzhiyun * Enable the master IRQ ...
1048*4882a593Smuzhiyun */
1049*4882a593Smuzhiyun sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x80);
1050*4882a593Smuzhiyun
1051*4882a593Smuzhiyun spin_unlock_irqrestore(&sscape->lock, flags);
1052*4882a593Smuzhiyun
1053*4882a593Smuzhiyun /*
1054*4882a593Smuzhiyun * We have now enabled the codec chip, and so we should
1055*4882a593Smuzhiyun * detect the AD1845 device ...
1056*4882a593Smuzhiyun */
1057*4882a593Smuzhiyun err = create_ad1845(card, wss_port[dev], irq[dev],
1058*4882a593Smuzhiyun dma[dev], dma2[dev]);
1059*4882a593Smuzhiyun if (err < 0) {
1060*4882a593Smuzhiyun snd_printk(KERN_ERR
1061*4882a593Smuzhiyun "sscape: No AD1845 device at 0x%lx, IRQ %d\n",
1062*4882a593Smuzhiyun wss_port[dev], irq[dev]);
1063*4882a593Smuzhiyun goto _release_dma;
1064*4882a593Smuzhiyun }
1065*4882a593Smuzhiyun strcpy(card->driver, "SoundScape");
1066*4882a593Smuzhiyun strcpy(card->shortname, name);
1067*4882a593Smuzhiyun snprintf(card->longname, sizeof(card->longname),
1068*4882a593Smuzhiyun "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n",
1069*4882a593Smuzhiyun name, sscape->chip->port, sscape->chip->irq,
1070*4882a593Smuzhiyun sscape->chip->dma1, sscape->chip->dma2);
1071*4882a593Smuzhiyun
1072*4882a593Smuzhiyun #define MIDI_DEVNUM 0
1073*4882a593Smuzhiyun if (sscape->type != SSCAPE_VIVO) {
1074*4882a593Smuzhiyun err = sscape_upload_bootblock(card);
1075*4882a593Smuzhiyun if (err >= 0)
1076*4882a593Smuzhiyun err = sscape_upload_microcode(card, err);
1077*4882a593Smuzhiyun
1078*4882a593Smuzhiyun if (err == 0) {
1079*4882a593Smuzhiyun err = create_mpu401(card, MIDI_DEVNUM, port[dev],
1080*4882a593Smuzhiyun mpu_irq[dev]);
1081*4882a593Smuzhiyun if (err < 0) {
1082*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Failed to create "
1083*4882a593Smuzhiyun "MPU-401 device at 0x%lx\n",
1084*4882a593Smuzhiyun port[dev]);
1085*4882a593Smuzhiyun goto _release_dma;
1086*4882a593Smuzhiyun }
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun /*
1089*4882a593Smuzhiyun * Initialize mixer
1090*4882a593Smuzhiyun */
1091*4882a593Smuzhiyun spin_lock_irqsave(&sscape->lock, flags);
1092*4882a593Smuzhiyun sscape->midi_vol = 0;
1093*4882a593Smuzhiyun host_write_ctrl_unsafe(sscape->io_base,
1094*4882a593Smuzhiyun CMD_SET_MIDI_VOL, 100);
1095*4882a593Smuzhiyun host_write_ctrl_unsafe(sscape->io_base,
1096*4882a593Smuzhiyun sscape->midi_vol, 100);
1097*4882a593Smuzhiyun host_write_ctrl_unsafe(sscape->io_base,
1098*4882a593Smuzhiyun CMD_XXX_MIDI_VOL, 100);
1099*4882a593Smuzhiyun host_write_ctrl_unsafe(sscape->io_base,
1100*4882a593Smuzhiyun sscape->midi_vol, 100);
1101*4882a593Smuzhiyun host_write_ctrl_unsafe(sscape->io_base,
1102*4882a593Smuzhiyun CMD_SET_EXTMIDI, 100);
1103*4882a593Smuzhiyun host_write_ctrl_unsafe(sscape->io_base,
1104*4882a593Smuzhiyun 0, 100);
1105*4882a593Smuzhiyun host_write_ctrl_unsafe(sscape->io_base, CMD_ACK, 100);
1106*4882a593Smuzhiyun
1107*4882a593Smuzhiyun set_midi_mode_unsafe(sscape->io_base);
1108*4882a593Smuzhiyun spin_unlock_irqrestore(&sscape->lock, flags);
1109*4882a593Smuzhiyun }
1110*4882a593Smuzhiyun }
1111*4882a593Smuzhiyun
1112*4882a593Smuzhiyun /*
1113*4882a593Smuzhiyun * Now that we have successfully created this sound card,
1114*4882a593Smuzhiyun * it is safe to store the pointer.
1115*4882a593Smuzhiyun * NOTE: we only register the sound card's "destructor"
1116*4882a593Smuzhiyun * function now that our "constructor" has completed.
1117*4882a593Smuzhiyun */
1118*4882a593Smuzhiyun card->private_free = soundscape_free;
1119*4882a593Smuzhiyun
1120*4882a593Smuzhiyun return 0;
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun _release_dma:
1123*4882a593Smuzhiyun free_dma(dma[dev]);
1124*4882a593Smuzhiyun
1125*4882a593Smuzhiyun _release_region:
1126*4882a593Smuzhiyun release_and_free_resource(wss_res);
1127*4882a593Smuzhiyun release_and_free_resource(io_res);
1128*4882a593Smuzhiyun
1129*4882a593Smuzhiyun return err;
1130*4882a593Smuzhiyun }
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun
snd_sscape_match(struct device * pdev,unsigned int i)1133*4882a593Smuzhiyun static int snd_sscape_match(struct device *pdev, unsigned int i)
1134*4882a593Smuzhiyun {
1135*4882a593Smuzhiyun /*
1136*4882a593Smuzhiyun * Make sure we were given ALL of the other parameters.
1137*4882a593Smuzhiyun */
1138*4882a593Smuzhiyun if (port[i] == SNDRV_AUTO_PORT)
1139*4882a593Smuzhiyun return 0;
1140*4882a593Smuzhiyun
1141*4882a593Smuzhiyun if (irq[i] == SNDRV_AUTO_IRQ ||
1142*4882a593Smuzhiyun mpu_irq[i] == SNDRV_AUTO_IRQ ||
1143*4882a593Smuzhiyun dma[i] == SNDRV_AUTO_DMA) {
1144*4882a593Smuzhiyun printk(KERN_INFO
1145*4882a593Smuzhiyun "sscape: insufficient parameters, "
1146*4882a593Smuzhiyun "need IO, IRQ, MPU-IRQ and DMA\n");
1147*4882a593Smuzhiyun return 0;
1148*4882a593Smuzhiyun }
1149*4882a593Smuzhiyun
1150*4882a593Smuzhiyun return 1;
1151*4882a593Smuzhiyun }
1152*4882a593Smuzhiyun
snd_sscape_probe(struct device * pdev,unsigned int dev)1153*4882a593Smuzhiyun static int snd_sscape_probe(struct device *pdev, unsigned int dev)
1154*4882a593Smuzhiyun {
1155*4882a593Smuzhiyun struct snd_card *card;
1156*4882a593Smuzhiyun struct soundscape *sscape;
1157*4882a593Smuzhiyun int ret;
1158*4882a593Smuzhiyun
1159*4882a593Smuzhiyun ret = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
1160*4882a593Smuzhiyun sizeof(struct soundscape), &card);
1161*4882a593Smuzhiyun if (ret < 0)
1162*4882a593Smuzhiyun return ret;
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun sscape = get_card_soundscape(card);
1165*4882a593Smuzhiyun sscape->type = SSCAPE;
1166*4882a593Smuzhiyun
1167*4882a593Smuzhiyun dma[dev] &= 0x03;
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun ret = create_sscape(dev, card);
1170*4882a593Smuzhiyun if (ret < 0)
1171*4882a593Smuzhiyun goto _release_card;
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun ret = snd_card_register(card);
1174*4882a593Smuzhiyun if (ret < 0) {
1175*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
1176*4882a593Smuzhiyun goto _release_card;
1177*4882a593Smuzhiyun }
1178*4882a593Smuzhiyun dev_set_drvdata(pdev, card);
1179*4882a593Smuzhiyun return 0;
1180*4882a593Smuzhiyun
1181*4882a593Smuzhiyun _release_card:
1182*4882a593Smuzhiyun snd_card_free(card);
1183*4882a593Smuzhiyun return ret;
1184*4882a593Smuzhiyun }
1185*4882a593Smuzhiyun
snd_sscape_remove(struct device * devptr,unsigned int dev)1186*4882a593Smuzhiyun static int snd_sscape_remove(struct device *devptr, unsigned int dev)
1187*4882a593Smuzhiyun {
1188*4882a593Smuzhiyun snd_card_free(dev_get_drvdata(devptr));
1189*4882a593Smuzhiyun return 0;
1190*4882a593Smuzhiyun }
1191*4882a593Smuzhiyun
1192*4882a593Smuzhiyun #define DEV_NAME "sscape"
1193*4882a593Smuzhiyun
1194*4882a593Smuzhiyun static struct isa_driver snd_sscape_driver = {
1195*4882a593Smuzhiyun .match = snd_sscape_match,
1196*4882a593Smuzhiyun .probe = snd_sscape_probe,
1197*4882a593Smuzhiyun .remove = snd_sscape_remove,
1198*4882a593Smuzhiyun /* FIXME: suspend/resume */
1199*4882a593Smuzhiyun .driver = {
1200*4882a593Smuzhiyun .name = DEV_NAME
1201*4882a593Smuzhiyun },
1202*4882a593Smuzhiyun };
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun #ifdef CONFIG_PNP
get_next_autoindex(int i)1205*4882a593Smuzhiyun static inline int get_next_autoindex(int i)
1206*4882a593Smuzhiyun {
1207*4882a593Smuzhiyun while (i < SNDRV_CARDS && port[i] != SNDRV_AUTO_PORT)
1208*4882a593Smuzhiyun ++i;
1209*4882a593Smuzhiyun return i;
1210*4882a593Smuzhiyun }
1211*4882a593Smuzhiyun
1212*4882a593Smuzhiyun
sscape_pnp_detect(struct pnp_card_link * pcard,const struct pnp_card_device_id * pid)1213*4882a593Smuzhiyun static int sscape_pnp_detect(struct pnp_card_link *pcard,
1214*4882a593Smuzhiyun const struct pnp_card_device_id *pid)
1215*4882a593Smuzhiyun {
1216*4882a593Smuzhiyun static int idx = 0;
1217*4882a593Smuzhiyun struct pnp_dev *dev;
1218*4882a593Smuzhiyun struct snd_card *card;
1219*4882a593Smuzhiyun struct soundscape *sscape;
1220*4882a593Smuzhiyun int ret;
1221*4882a593Smuzhiyun
1222*4882a593Smuzhiyun /*
1223*4882a593Smuzhiyun * Allow this function to fail *quietly* if all the ISA PnP
1224*4882a593Smuzhiyun * devices were configured using module parameters instead.
1225*4882a593Smuzhiyun */
1226*4882a593Smuzhiyun idx = get_next_autoindex(idx);
1227*4882a593Smuzhiyun if (idx >= SNDRV_CARDS)
1228*4882a593Smuzhiyun return -ENOSPC;
1229*4882a593Smuzhiyun
1230*4882a593Smuzhiyun /*
1231*4882a593Smuzhiyun * Check that we still have room for another sound card ...
1232*4882a593Smuzhiyun */
1233*4882a593Smuzhiyun dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
1234*4882a593Smuzhiyun if (!dev)
1235*4882a593Smuzhiyun return -ENODEV;
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun if (!pnp_is_active(dev)) {
1238*4882a593Smuzhiyun if (pnp_activate_dev(dev) < 0) {
1239*4882a593Smuzhiyun snd_printk(KERN_INFO "sscape: device is inactive\n");
1240*4882a593Smuzhiyun return -EBUSY;
1241*4882a593Smuzhiyun }
1242*4882a593Smuzhiyun }
1243*4882a593Smuzhiyun
1244*4882a593Smuzhiyun /*
1245*4882a593Smuzhiyun * Create a new ALSA sound card entry, in anticipation
1246*4882a593Smuzhiyun * of detecting our hardware ...
1247*4882a593Smuzhiyun */
1248*4882a593Smuzhiyun ret = snd_card_new(&pcard->card->dev,
1249*4882a593Smuzhiyun index[idx], id[idx], THIS_MODULE,
1250*4882a593Smuzhiyun sizeof(struct soundscape), &card);
1251*4882a593Smuzhiyun if (ret < 0)
1252*4882a593Smuzhiyun return ret;
1253*4882a593Smuzhiyun
1254*4882a593Smuzhiyun sscape = get_card_soundscape(card);
1255*4882a593Smuzhiyun
1256*4882a593Smuzhiyun /*
1257*4882a593Smuzhiyun * Identify card model ...
1258*4882a593Smuzhiyun */
1259*4882a593Smuzhiyun if (!strncmp("ENS4081", pid->id, 7))
1260*4882a593Smuzhiyun sscape->type = SSCAPE_VIVO;
1261*4882a593Smuzhiyun else
1262*4882a593Smuzhiyun sscape->type = SSCAPE_PNP;
1263*4882a593Smuzhiyun
1264*4882a593Smuzhiyun /*
1265*4882a593Smuzhiyun * Read the correct parameters off the ISA PnP bus ...
1266*4882a593Smuzhiyun */
1267*4882a593Smuzhiyun port[idx] = pnp_port_start(dev, 0);
1268*4882a593Smuzhiyun irq[idx] = pnp_irq(dev, 0);
1269*4882a593Smuzhiyun mpu_irq[idx] = pnp_irq(dev, 1);
1270*4882a593Smuzhiyun dma[idx] = pnp_dma(dev, 0) & 0x03;
1271*4882a593Smuzhiyun if (sscape->type == SSCAPE_PNP) {
1272*4882a593Smuzhiyun dma2[idx] = dma[idx];
1273*4882a593Smuzhiyun wss_port[idx] = CODEC_IO(port[idx]);
1274*4882a593Smuzhiyun } else {
1275*4882a593Smuzhiyun wss_port[idx] = pnp_port_start(dev, 1);
1276*4882a593Smuzhiyun dma2[idx] = pnp_dma(dev, 1);
1277*4882a593Smuzhiyun }
1278*4882a593Smuzhiyun
1279*4882a593Smuzhiyun ret = create_sscape(idx, card);
1280*4882a593Smuzhiyun if (ret < 0)
1281*4882a593Smuzhiyun goto _release_card;
1282*4882a593Smuzhiyun
1283*4882a593Smuzhiyun ret = snd_card_register(card);
1284*4882a593Smuzhiyun if (ret < 0) {
1285*4882a593Smuzhiyun snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
1286*4882a593Smuzhiyun goto _release_card;
1287*4882a593Smuzhiyun }
1288*4882a593Smuzhiyun
1289*4882a593Smuzhiyun pnp_set_card_drvdata(pcard, card);
1290*4882a593Smuzhiyun ++idx;
1291*4882a593Smuzhiyun return 0;
1292*4882a593Smuzhiyun
1293*4882a593Smuzhiyun _release_card:
1294*4882a593Smuzhiyun snd_card_free(card);
1295*4882a593Smuzhiyun return ret;
1296*4882a593Smuzhiyun }
1297*4882a593Smuzhiyun
sscape_pnp_remove(struct pnp_card_link * pcard)1298*4882a593Smuzhiyun static void sscape_pnp_remove(struct pnp_card_link *pcard)
1299*4882a593Smuzhiyun {
1300*4882a593Smuzhiyun snd_card_free(pnp_get_card_drvdata(pcard));
1301*4882a593Smuzhiyun pnp_set_card_drvdata(pcard, NULL);
1302*4882a593Smuzhiyun }
1303*4882a593Smuzhiyun
1304*4882a593Smuzhiyun static struct pnp_card_driver sscape_pnpc_driver = {
1305*4882a593Smuzhiyun .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
1306*4882a593Smuzhiyun .name = "sscape",
1307*4882a593Smuzhiyun .id_table = sscape_pnpids,
1308*4882a593Smuzhiyun .probe = sscape_pnp_detect,
1309*4882a593Smuzhiyun .remove = sscape_pnp_remove,
1310*4882a593Smuzhiyun };
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun #endif /* CONFIG_PNP */
1313*4882a593Smuzhiyun
sscape_init(void)1314*4882a593Smuzhiyun static int __init sscape_init(void)
1315*4882a593Smuzhiyun {
1316*4882a593Smuzhiyun int err;
1317*4882a593Smuzhiyun
1318*4882a593Smuzhiyun err = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
1319*4882a593Smuzhiyun #ifdef CONFIG_PNP
1320*4882a593Smuzhiyun if (!err)
1321*4882a593Smuzhiyun isa_registered = 1;
1322*4882a593Smuzhiyun
1323*4882a593Smuzhiyun err = pnp_register_card_driver(&sscape_pnpc_driver);
1324*4882a593Smuzhiyun if (!err)
1325*4882a593Smuzhiyun pnp_registered = 1;
1326*4882a593Smuzhiyun
1327*4882a593Smuzhiyun if (isa_registered)
1328*4882a593Smuzhiyun err = 0;
1329*4882a593Smuzhiyun #endif
1330*4882a593Smuzhiyun return err;
1331*4882a593Smuzhiyun }
1332*4882a593Smuzhiyun
sscape_exit(void)1333*4882a593Smuzhiyun static void __exit sscape_exit(void)
1334*4882a593Smuzhiyun {
1335*4882a593Smuzhiyun #ifdef CONFIG_PNP
1336*4882a593Smuzhiyun if (pnp_registered)
1337*4882a593Smuzhiyun pnp_unregister_card_driver(&sscape_pnpc_driver);
1338*4882a593Smuzhiyun if (isa_registered)
1339*4882a593Smuzhiyun #endif
1340*4882a593Smuzhiyun isa_unregister_driver(&snd_sscape_driver);
1341*4882a593Smuzhiyun }
1342*4882a593Smuzhiyun
1343*4882a593Smuzhiyun module_init(sscape_init);
1344*4882a593Smuzhiyun module_exit(sscape_exit);
1345