~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/isa/opl3sa2.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/isa/opl3sa2.c (Version linux-6.12-rc7) and /sound/isa/opl3sa2.c (Version linux-5.15.169)


** Warning: Cannot open xref database.

  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  *  Driver for Yamaha OPL3-SA[2,3] soundcards     
  4  *  Copyright (c) by Jaroslav Kysela <perex@pe    
  5  */                                               
  6                                                   
  7 #include <linux/init.h>                           
  8 #include <linux/err.h>                            
  9 #include <linux/isa.h>                            
 10 #include <linux/interrupt.h>                      
 11 #include <linux/pm.h>                             
 12 #include <linux/pnp.h>                            
 13 #include <linux/module.h>                         
 14 #include <linux/io.h>                             
 15 #include <sound/core.h>                           
 16 #include <sound/wss.h>                            
 17 #include <sound/mpu401.h>                         
 18 #include <sound/opl3.h>                           
 19 #include <sound/initval.h>                        
 20 #include <sound/tlv.h>                            
 21                                                   
 22 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz    
 23 MODULE_DESCRIPTION("Yamaha OPL3SA2+");            
 24 MODULE_LICENSE("GPL");                            
 25                                                   
 26 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_    
 27 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_S    
 28 static bool enable[SNDRV_CARDS] = SNDRV_DEFAUL    
 29 #ifdef CONFIG_PNP                                 
 30 static bool isapnp[SNDRV_CARDS] = {[0 ... (SND    
 31 #endif                                            
 32 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_    
 33 static long sb_port[SNDRV_CARDS] = SNDRV_DEFAU    
 34 static long wss_port[SNDRV_CARDS] = SNDRV_DEFA    
 35 static long fm_port[SNDRV_CARDS] = SNDRV_DEFAU    
 36 static long midi_port[SNDRV_CARDS] = SNDRV_DEF    
 37 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IR    
 38 static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_D    
 39 static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_D    
 40 static int opl3sa3_ymode[SNDRV_CARDS];   /* 0,    
 41                                                   
 42 module_param_array(index, int, NULL, 0444);       
 43 MODULE_PARM_DESC(index, "Index value for OPL3-    
 44 module_param_array(id, charp, NULL, 0444);        
 45 MODULE_PARM_DESC(id, "ID string for OPL3-SA so    
 46 module_param_array(enable, bool, NULL, 0444);     
 47 MODULE_PARM_DESC(enable, "Enable OPL3-SA sound    
 48 #ifdef CONFIG_PNP                                 
 49 module_param_array(isapnp, bool, NULL, 0444);     
 50 MODULE_PARM_DESC(isapnp, "PnP detection for sp    
 51 #endif                                            
 52 module_param_hw_array(port, long, ioport, NULL    
 53 MODULE_PARM_DESC(port, "Port # for OPL3-SA dri    
 54 module_param_hw_array(sb_port, long, ioport, N    
 55 MODULE_PARM_DESC(sb_port, "SB port # for OPL3-    
 56 module_param_hw_array(wss_port, long, ioport,     
 57 MODULE_PARM_DESC(wss_port, "WSS port # for OPL    
 58 module_param_hw_array(fm_port, long, ioport, N    
 59 MODULE_PARM_DESC(fm_port, "FM port # for OPL3-    
 60 module_param_hw_array(midi_port, long, ioport,    
 61 MODULE_PARM_DESC(midi_port, "MIDI port # for O    
 62 module_param_hw_array(irq, int, irq, NULL, 044    
 63 MODULE_PARM_DESC(irq, "IRQ # for OPL3-SA drive    
 64 module_param_hw_array(dma1, int, dma, NULL, 04    
 65 MODULE_PARM_DESC(dma1, "DMA1 # for OPL3-SA dri    
 66 module_param_hw_array(dma2, int, dma, NULL, 04    
 67 MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA dri    
 68 module_param_array(opl3sa3_ymode, int, NULL, 0    
 69 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size     
 70                                                   
 71 #ifdef CONFIG_PNP                                 
 72 static int isa_registered;                        
 73 static int pnp_registered;                        
 74 static int pnpc_registered;                       
 75 #endif                                            
 76                                                   
 77 /* control ports */                               
 78 #define OPL3SA2_PM_CTRL         0x01              
 79 #define OPL3SA2_SYS_CTRL                0x02      
 80 #define OPL3SA2_IRQ_CONFIG      0x03              
 81 #define OPL3SA2_IRQ_STATUS      0x04              
 82 #define OPL3SA2_DMA_CONFIG      0x06              
 83 #define OPL3SA2_MASTER_LEFT     0x07              
 84 #define OPL3SA2_MASTER_RIGHT    0x08              
 85 #define OPL3SA2_MIC             0x09              
 86 #define OPL3SA2_MISC            0x0A              
 87                                                   
 88 /* opl3sa3 only */                                
 89 #define OPL3SA3_DGTL_DOWN       0x12              
 90 #define OPL3SA3_ANLG_DOWN       0x13              
 91 #define OPL3SA3_WIDE            0x14              
 92 #define OPL3SA3_BASS            0x15              
 93 #define OPL3SA3_TREBLE          0x16              
 94                                                   
 95 /* power management bits */                       
 96 #define OPL3SA2_PM_ADOWN                0x20      
 97 #define OPL3SA2_PM_PSV          0x04              
 98 #define OPL3SA2_PM_PDN          0x02              
 99 #define OPL3SA2_PM_PDX          0x01              
100                                                   
101 #define OPL3SA2_PM_D0   0x00                      
102 #define OPL3SA2_PM_D3   (OPL3SA2_PM_ADOWN|OPL3    
103                                                   
104 struct snd_opl3sa2 {                              
105         int version;            /* 2 or 3 */      
106         unsigned long port;     /* control por    
107         struct resource *res_port; /* control     
108         int irq;                                  
109         int single_dma;                           
110         spinlock_t reg_lock;                      
111         struct snd_card *card;                    
112         struct snd_hwdep *synth;                  
113         struct snd_rawmidi *rmidi;                
114         struct snd_wss *wss;                      
115         unsigned char ctlregs[0x20];              
116         int ymode;              /* SL added */    
117         struct snd_kcontrol *master_switch;       
118         struct snd_kcontrol *master_volume;       
119 };                                                
120                                                   
121 #define PFX     "opl3sa2: "                       
122                                                   
123 #ifdef CONFIG_PNP                                 
124                                                   
125 static const struct pnp_device_id snd_opl3sa2_    
126         { .id = "YMH0021" },                      
127         { .id = "NMX2210" },    /* Gateway Sol    
128         { .id = "" }            /* end */         
129 };                                                
130                                                   
131 MODULE_DEVICE_TABLE(pnp, snd_opl3sa2_pnpbiosid    
132                                                   
133 static const struct pnp_card_device_id snd_opl    
134         /* Yamaha YMF719E-S (Genius Sound Make    
135         { .id = "YMH0020", .devs = { { "YMH002    
136         /* Yamaha OPL3-SA3 (integrated on Inte    
137         { .id = "YMH0030", .devs = { { "YMH002    
138         /* Yamaha OPL3-SA2 */                     
139         { .id = "YMH0800", .devs = { { "YMH002    
140         /* Yamaha OPL3-SA2 */                     
141         { .id = "YMH0801", .devs = { { "YMH002    
142         /* NeoMagic MagicWave 3DX */              
143         { .id = "NMX2200", .devs = { { "YMH221    
144         /* NeoMagic MagicWave 3D */               
145         { .id = "NMX2200", .devs = { { "NMX221    
146         /* --- */                                 
147         { .id = "" }    /* end */                 
148 };                                                
149                                                   
150 MODULE_DEVICE_TABLE(pnp_card, snd_opl3sa2_pnpi    
151                                                   
152 #endif /* CONFIG_PNP */                           
153                                                   
154                                                   
155 /* read control port (w/o spinlock) */            
156 static unsigned char __snd_opl3sa2_read(struct    
157 {                                                 
158         unsigned char result;                     
159 #if 0                                             
160         outb(0x1d, port);       /* password */    
161         dev_dbg(chip->card->dev, "read [0x%lx]    
162 #endif                                            
163         outb(reg, chip->port);  /* register */    
164         result = inb(chip->port + 1);             
165 #if 0                                             
166         dev_dbg(chip->card->dev, "read [0x%lx]    
167                port, result, inb(port));          
168 #endif                                            
169         return result;                            
170 }                                                 
171                                                   
172 /* read control port (with spinlock) */           
173 static unsigned char snd_opl3sa2_read(struct s    
174 {                                                 
175         unsigned long flags;                      
176         unsigned char result;                     
177                                                   
178         spin_lock_irqsave(&chip->reg_lock, fla    
179         result = __snd_opl3sa2_read(chip, reg)    
180         spin_unlock_irqrestore(&chip->reg_lock    
181         return result;                            
182 }                                                 
183                                                   
184 /* write control port (w/o spinlock) */           
185 static void __snd_opl3sa2_write(struct snd_opl    
186 {                                                 
187 #if 0                                             
188         outb(0x1d, port);       /* password */    
189 #endif                                            
190         outb(reg, chip->port);  /* register */    
191         outb(value, chip->port + 1);              
192         chip->ctlregs[reg] = value;               
193 }                                                 
194                                                   
195 /* write control port (with spinlock) */          
196 static void snd_opl3sa2_write(struct snd_opl3s    
197 {                                                 
198         unsigned long flags;                      
199         spin_lock_irqsave(&chip->reg_lock, fla    
200         __snd_opl3sa2_write(chip, reg, value);    
201         spin_unlock_irqrestore(&chip->reg_lock    
202 }                                                 
203                                                   
204 static int snd_opl3sa2_detect(struct snd_card     
205 {                                                 
206         struct snd_opl3sa2 *chip = card->priva    
207         unsigned long port;                       
208         unsigned char tmp, tmp1;                  
209         char str[2];                              
210                                                   
211         port = chip->port;                        
212         chip->res_port = devm_request_region(c    
213                                              "    
214         if (!chip->res_port) {                    
215                 dev_err(card->dev, "can't grab    
216                 return -EBUSY;                    
217         }                                         
218         chip->version = 0;                        
219         tmp = snd_opl3sa2_read(chip, OPL3SA2_M    
220         if (tmp == 0xff) {                        
221                 dev_dbg(card->dev, "OPL3-SA [0    
222                 return -ENODEV;                   
223         }                                         
224         switch (tmp & 0x07) {                     
225         case 0x01:                                
226                 chip->version = 2; /* YMF711 *    
227                 break;                            
228         default:                                  
229                 chip->version = 3;                
230                 /* 0x02 - standard */             
231                 /* 0x03 - YM715B */               
232                 /* 0x04 - YM719 - OPL-SA4? */     
233                 /* 0x05 - OPL3-SA3 - Libretto     
234                 /* 0x07 - unknown - Neomagic M    
235                 break;                            
236         }                                         
237         str[0] = chip->version + '';              
238         str[1] = 0;                               
239         strcat(card->shortname, str);             
240         snd_opl3sa2_write(chip, OPL3SA2_MISC,     
241         tmp1 = snd_opl3sa2_read(chip, OPL3SA2_    
242         if (tmp1 != tmp) {                        
243                 dev_dbg(card->dev, "OPL3-SA [0    
244                 return -ENODEV;                   
245         }                                         
246         /* try if the MIC register is accessib    
247         tmp = snd_opl3sa2_read(chip, OPL3SA2_M    
248         snd_opl3sa2_write(chip, OPL3SA2_MIC, 0    
249         tmp1 = snd_opl3sa2_read(chip, OPL3SA2_    
250         if ((tmp1 & 0x9f) != 0x8a) {              
251                 dev_dbg(card->dev, "OPL3-SA [0    
252                 return -ENODEV;                   
253         }                                         
254         snd_opl3sa2_write(chip, OPL3SA2_MIC, 0    
255         /* initialization */                      
256         /* Power Management - full on */          
257         snd_opl3sa2_write(chip, OPL3SA2_PM_CTR    
258         if (chip->version > 2) {                  
259                 /* ymode is bits 4&5 (of 0 to     
260                 snd_opl3sa2_write(chip, OPL3SA    
261         } else {                                  
262                 /* default for opl3sa2 version    
263                 snd_opl3sa2_write(chip, OPL3SA    
264         }                                         
265         snd_opl3sa2_write(chip, OPL3SA2_IRQ_CO    
266         if (chip->single_dma) {                   
267                 snd_opl3sa2_write(chip, OPL3SA    
268         } else {                                  
269                 snd_opl3sa2_write(chip, OPL3SA    
270         }                                         
271         snd_opl3sa2_write(chip, OPL3SA2_MISC,     
272         if (chip->version > 2) {                  
273                 snd_opl3sa2_write(chip, OPL3SA    
274                 snd_opl3sa2_write(chip, OPL3SA    
275         }                                         
276         return 0;                                 
277 }                                                 
278                                                   
279 static irqreturn_t snd_opl3sa2_interrupt(int i    
280 {                                                 
281         unsigned short status;                    
282         struct snd_card *card = dev_id;           
283         struct snd_opl3sa2 *chip;                 
284         int handled = 0;                          
285                                                   
286         if (card == NULL)                         
287                 return IRQ_NONE;                  
288                                                   
289         chip = card->private_data;                
290         status = snd_opl3sa2_read(chip, OPL3SA    
291                                                   
292         if (status & 0x20) {                      
293                 handled = 1;                      
294                 snd_opl3_interrupt(chip->synth    
295         }                                         
296                                                   
297         if ((status & 0x10) && chip->rmidi !=     
298                 handled = 1;                      
299                 snd_mpu401_uart_interrupt(irq,    
300         }                                         
301                                                   
302         if (status & 0x07) {    /* TI,CI,PI */    
303                 handled = 1;                      
304                 snd_wss_interrupt(irq, chip->w    
305         }                                         
306                                                   
307         if (status & 0x40) { /* hardware volum    
308                 handled = 1;                      
309                 /* reading from Master Lch reg    
310                 snd_opl3sa2_read(chip, OPL3SA2    
311                 snd_opl3sa2_read(chip, OPL3SA2    
312                 if (chip->master_switch && chi    
313                         snd_ctl_notify(card, S    
314                                         &chip-    
315                         snd_ctl_notify(card, S    
316                                         &chip-    
317                 }                                 
318         }                                         
319         return IRQ_RETVAL(handled);               
320 }                                                 
321                                                   
322 #define OPL3SA2_SINGLE(xname, xindex, reg, shi    
323 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name =    
324   .info = snd_wss_info_single, \                  
325   .get = snd_opl3sa2_get_single, .put = snd_op    
326   .private_value = reg | (shift << 8) | (mask     
327 #define OPL3SA2_SINGLE_TLV(xname, xindex, reg,    
328 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \          
329   .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |     
330   .name = xname, .index = xindex, \               
331   .info = snd_wss_info_single, \                  
332   .get = snd_opl3sa2_get_single, .put = snd_op    
333   .private_value = reg | (shift << 8) | (mask     
334   .tlv = { .p = (xtlv) } }                        
335                                                   
336 static int snd_opl3sa2_get_single(struct snd_k    
337 {                                                 
338         struct snd_opl3sa2 *chip = snd_kcontro    
339         unsigned long flags;                      
340         int reg = kcontrol->private_value & 0x    
341         int shift = (kcontrol->private_value >    
342         int mask = (kcontrol->private_value >>    
343         int invert = (kcontrol->private_value     
344                                                   
345         spin_lock_irqsave(&chip->reg_lock, fla    
346         ucontrol->value.integer.value[0] = (ch    
347         spin_unlock_irqrestore(&chip->reg_lock    
348         if (invert)                               
349                 ucontrol->value.integer.value[    
350         return 0;                                 
351 }                                                 
352                                                   
353 static int snd_opl3sa2_put_single(struct snd_k    
354 {                                                 
355         struct snd_opl3sa2 *chip = snd_kcontro    
356         unsigned long flags;                      
357         int reg = kcontrol->private_value & 0x    
358         int shift = (kcontrol->private_value >    
359         int mask = (kcontrol->private_value >>    
360         int invert = (kcontrol->private_value     
361         int change;                               
362         unsigned short val, oval;                 
363                                                   
364         val = (ucontrol->value.integer.value[0    
365         if (invert)                               
366                 val = mask - val;                 
367         val <<= shift;                            
368         spin_lock_irqsave(&chip->reg_lock, fla    
369         oval = chip->ctlregs[reg];                
370         val = (oval & ~(mask << shift)) | val;    
371         change = val != oval;                     
372         __snd_opl3sa2_write(chip, reg, val);      
373         spin_unlock_irqrestore(&chip->reg_lock    
374         return change;                            
375 }                                                 
376                                                   
377 #define OPL3SA2_DOUBLE(xname, xindex, left_reg    
378 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name =    
379   .info = snd_wss_info_double, \                  
380   .get = snd_opl3sa2_get_double, .put = snd_op    
381   .private_value = left_reg | (right_reg << 8)    
382 #define OPL3SA2_DOUBLE_TLV(xname, xindex, left    
383 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \          
384   .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |     
385   .name = xname, .index = xindex, \               
386   .info = snd_wss_info_double, \                  
387   .get = snd_opl3sa2_get_double, .put = snd_op    
388   .private_value = left_reg | (right_reg << 8)    
389   .tlv = { .p = (xtlv) } }                        
390                                                   
391 static int snd_opl3sa2_get_double(struct snd_k    
392 {                                                 
393         struct snd_opl3sa2 *chip = snd_kcontro    
394         unsigned long flags;                      
395         int left_reg = kcontrol->private_value    
396         int right_reg = (kcontrol->private_val    
397         int shift_left = (kcontrol->private_va    
398         int shift_right = (kcontrol->private_v    
399         int mask = (kcontrol->private_value >>    
400         int invert = (kcontrol->private_value     
401                                                   
402         spin_lock_irqsave(&chip->reg_lock, fla    
403         ucontrol->value.integer.value[0] = (ch    
404         ucontrol->value.integer.value[1] = (ch    
405         spin_unlock_irqrestore(&chip->reg_lock    
406         if (invert) {                             
407                 ucontrol->value.integer.value[    
408                 ucontrol->value.integer.value[    
409         }                                         
410         return 0;                                 
411 }                                                 
412                                                   
413 static int snd_opl3sa2_put_double(struct snd_k    
414 {                                                 
415         struct snd_opl3sa2 *chip = snd_kcontro    
416         unsigned long flags;                      
417         int left_reg = kcontrol->private_value    
418         int right_reg = (kcontrol->private_val    
419         int shift_left = (kcontrol->private_va    
420         int shift_right = (kcontrol->private_v    
421         int mask = (kcontrol->private_value >>    
422         int invert = (kcontrol->private_value     
423         int change;                               
424         unsigned short val1, val2, oval1, oval    
425                                                   
426         val1 = ucontrol->value.integer.value[0    
427         val2 = ucontrol->value.integer.value[1    
428         if (invert) {                             
429                 val1 = mask - val1;               
430                 val2 = mask - val2;               
431         }                                         
432         val1 <<= shift_left;                      
433         val2 <<= shift_right;                     
434         spin_lock_irqsave(&chip->reg_lock, fla    
435         if (left_reg != right_reg) {              
436                 oval1 = chip->ctlregs[left_reg    
437                 oval2 = chip->ctlregs[right_re    
438                 val1 = (oval1 & ~(mask << shif    
439                 val2 = (oval2 & ~(mask << shif    
440                 change = val1 != oval1 || val2    
441                 __snd_opl3sa2_write(chip, left    
442                 __snd_opl3sa2_write(chip, righ    
443         } else {                                  
444                 oval1 = chip->ctlregs[left_reg    
445                 val1 = (oval1 & ~((mask << shi    
446                 change = val1 != oval1;           
447                 __snd_opl3sa2_write(chip, left    
448         }                                         
449         spin_unlock_irqrestore(&chip->reg_lock    
450         return change;                            
451 }                                                 
452                                                   
453 static const DECLARE_TLV_DB_SCALE(db_scale_mas    
454 static const DECLARE_TLV_DB_SCALE(db_scale_5bi    
455                                                   
456 static const struct snd_kcontrol_new snd_opl3s    
457 OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x    
458 OPL3SA2_DOUBLE_TLV("Master Playback Volume", 0    
459                    db_scale_master),              
460 OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09,    
461 OPL3SA2_SINGLE_TLV("Mic Playback Volume", 0, 0    
462                    db_scale_5bit_12db_max),       
463 OPL3SA2_SINGLE("ZV Port Switch", 0, 0x02, 0, 1    
464 };                                                
465                                                   
466 static const struct snd_kcontrol_new snd_opl3s    
467 OPL3SA2_DOUBLE("3D Control - Wide", 0, 0x14, 0    
468 OPL3SA2_DOUBLE("Tone Control - Bass", 0, 0x15,    
469 OPL3SA2_DOUBLE("Tone Control - Treble", 0, 0x1    
470 };                                                
471                                                   
472 static void snd_opl3sa2_master_free(struct snd    
473 {                                                 
474         struct snd_opl3sa2 *chip = snd_kcontro    
475         chip->master_switch = NULL;               
476         chip->master_volume = NULL;               
477 }                                                 
478                                                   
479 static int snd_opl3sa2_mixer(struct snd_card *    
480 {                                                 
481         struct snd_opl3sa2 *chip = card->priva    
482         struct snd_ctl_elem_id id1, id2;          
483         struct snd_kcontrol *kctl;                
484         unsigned int idx;                         
485         int err;                                  
486                                                   
487         memset(&id1, 0, sizeof(id1));             
488         memset(&id2, 0, sizeof(id2));             
489         id1.iface = id2.iface = SNDRV_CTL_ELEM    
490         /* reassign AUX0 to CD */                 
491         strcpy(id1.name, "Aux Playback Switch"    
492         strcpy(id2.name, "CD Playback Switch")    
493         err = snd_ctl_rename_id(card, &id1, &i    
494         if (err < 0) {                            
495                 dev_err(card->dev, "Cannot ren    
496                 return err;                       
497         }                                         
498         strcpy(id1.name, "Aux Playback Volume"    
499         strcpy(id2.name, "CD Playback Volume")    
500         err = snd_ctl_rename_id(card, &id1, &i    
501         if (err < 0) {                            
502                 dev_err(card->dev, "Cannot ren    
503                 return err;                       
504         }                                         
505         /* reassign AUX1 to FM */                 
506         strcpy(id1.name, "Aux Playback Switch"    
507         strcpy(id2.name, "FM Playback Switch")    
508         err = snd_ctl_rename_id(card, &id1, &i    
509         if (err < 0) {                            
510                 dev_err(card->dev, "Cannot ren    
511                 return err;                       
512         }                                         
513         strcpy(id1.name, "Aux Playback Volume"    
514         strcpy(id2.name, "FM Playback Volume")    
515         err = snd_ctl_rename_id(card, &id1, &i    
516         if (err < 0) {                            
517                 dev_err(card->dev, "Cannot ren    
518                 return err;                       
519         }                                         
520         /* add OPL3SA2 controls */                
521         for (idx = 0; idx < ARRAY_SIZE(snd_opl    
522                 kctl = snd_ctl_new1(&snd_opl3s    
523                 err = snd_ctl_add(card, kctl);    
524                 if (err < 0)                      
525                         return err;               
526                 switch (idx) {                    
527                 case 0: chip->master_switch =     
528                 case 1: chip->master_volume =     
529                 }                                 
530         }                                         
531         if (chip->version > 2) {                  
532                 for (idx = 0; idx < ARRAY_SIZE    
533                         err = snd_ctl_add(card    
534                         if (err < 0)              
535                                 return err;       
536                 }                                 
537         }                                         
538         return 0;                                 
539 }                                                 
540                                                   
541 /* Power Management support functions */          
542 #ifdef CONFIG_PM                                  
543 static int snd_opl3sa2_suspend(struct snd_card    
544 {                                                 
545         if (card) {                               
546                 struct snd_opl3sa2 *chip = car    
547                                                   
548                 snd_power_change_state(card, S    
549                 chip->wss->suspend(chip->wss);    
550                 /* power down */                  
551                 snd_opl3sa2_write(chip, OPL3SA    
552         }                                         
553                                                   
554         return 0;                                 
555 }                                                 
556                                                   
557 static int snd_opl3sa2_resume(struct snd_card     
558 {                                                 
559         struct snd_opl3sa2 *chip;                 
560         int i;                                    
561                                                   
562         if (!card)                                
563                 return 0;                         
564                                                   
565         chip = card->private_data;                
566         /* power up */                            
567         snd_opl3sa2_write(chip, OPL3SA2_PM_CTR    
568                                                   
569         /* restore registers */                   
570         for (i = 2; i <= 0x0a; i++) {             
571                 if (i != OPL3SA2_IRQ_STATUS)      
572                         snd_opl3sa2_write(chip    
573         }                                         
574         if (chip->version > 2) {                  
575                 for (i = 0x12; i <= 0x16; i++)    
576                         snd_opl3sa2_write(chip    
577         }                                         
578         /* restore wss */                         
579         chip->wss->resume(chip->wss);             
580                                                   
581         snd_power_change_state(card, SNDRV_CTL    
582         return 0;                                 
583 }                                                 
584 #endif /* CONFIG_PM */                            
585                                                   
586 #ifdef CONFIG_PNP                                 
587 static int snd_opl3sa2_pnp(int dev, struct snd    
588                            struct pnp_dev *pde    
589 {                                                 
590         if (pnp_activate_dev(pdev) < 0) {         
591                 dev_err(chip->card->dev, "PnP     
592                 return -EBUSY;                    
593         }                                         
594         sb_port[dev] = pnp_port_start(pdev, 0)    
595         wss_port[dev] = pnp_port_start(pdev, 1    
596         fm_port[dev] = pnp_port_start(pdev, 2)    
597         midi_port[dev] = pnp_port_start(pdev,     
598         port[dev] = pnp_port_start(pdev, 4);      
599         dma1[dev] = pnp_dma(pdev, 0);             
600         dma2[dev] = pnp_dma(pdev, 1);             
601         irq[dev] = pnp_irq(pdev, 0);              
602         dev_dbg(chip->card->dev, "%sPnP OPL3-S    
603                 pnp_device_is_pnpbios(pdev) ?     
604         dev_dbg(chip->card->dev, "%sPnP OPL3-S    
605                 pnp_device_is_pnpbios(pdev) ?     
606         return 0;                                 
607 }                                                 
608 #endif /* CONFIG_PNP */                           
609                                                   
610 static int snd_opl3sa2_card_new(struct device     
611                                 struct snd_car    
612 {                                                 
613         struct snd_card *card;                    
614         struct snd_opl3sa2 *chip;                 
615         int err;                                  
616                                                   
617         err = snd_devm_card_new(pdev, index[de    
618                                 sizeof(struct     
619         if (err < 0)                              
620                 return err;                       
621         strcpy(card->driver, "OPL3SA2");          
622         strcpy(card->shortname, "Yamaha OPL3-S    
623         chip = card->private_data;                
624         spin_lock_init(&chip->reg_lock);          
625         chip->irq = -1;                           
626         *cardp = card;                            
627         return 0;                                 
628 }                                                 
629                                                   
630 static int snd_opl3sa2_probe(struct snd_card *    
631 {                                                 
632         int xirq, xdma1, xdma2;                   
633         struct snd_opl3sa2 *chip;                 
634         struct snd_wss *wss;                      
635         struct snd_opl3 *opl3;                    
636         int err;                                  
637                                                   
638         /* initialise this card from supplied     
639         chip = card->private_data;                
640         chip->card = card;                        
641         chip->ymode = opl3sa3_ymode[dev] & 0x0    
642         chip->port = port[dev];                   
643         xirq = irq[dev];                          
644         xdma1 = dma1[dev];                        
645         xdma2 = dma2[dev];                        
646         if (xdma2 < 0)                            
647                 chip->single_dma = 1;             
648         err = snd_opl3sa2_detect(card);           
649         if (err < 0)                              
650                 return err;                       
651         err = devm_request_irq(card->dev, xirq    
652                                "OPL3-SA2", car    
653         if (err) {                                
654                 dev_err(card->dev, "can't grab    
655                 return -ENODEV;                   
656         }                                         
657         chip->irq = xirq;                         
658         card->sync_irq = chip->irq;               
659         err = snd_wss_create(card,                
660                              wss_port[dev] + 4    
661                              xirq, xdma1, xdma    
662                              WSS_HW_OPL3SA2, W    
663         if (err < 0) {                            
664                 dev_dbg(card->dev, "Oops, WSS     
665                 return err;                       
666         }                                         
667         chip->wss = wss;                          
668         err = snd_wss_pcm(wss, 0);                
669         if (err < 0)                              
670                 return err;                       
671         err = snd_wss_mixer(wss);                 
672         if (err < 0)                              
673                 return err;                       
674         err = snd_opl3sa2_mixer(card);            
675         if (err < 0)                              
676                 return err;                       
677         err = snd_wss_timer(wss, 0);              
678         if (err < 0)                              
679                 return err;                       
680         if (fm_port[dev] >= 0x340 && fm_port[d    
681                 err = snd_opl3_create(card, fm    
682                                       fm_port[    
683                                       OPL3_HW_    
684                 if (err < 0)                      
685                         return err;               
686                 err = snd_opl3_timer_new(opl3,    
687                 if (err < 0)                      
688                         return err;               
689                 err = snd_opl3_hwdep_new(opl3,    
690                 if (err < 0)                      
691                         return err;               
692         }                                         
693         if (midi_port[dev] >= 0x300 && midi_po    
694                 err = snd_mpu401_uart_new(card    
695                                           midi    
696                                           MPU4    
697                                           &chi    
698                 if (err < 0)                      
699                         return err;               
700         }                                         
701         sprintf(card->longname, "%s at 0x%lx,     
702                 card->shortname, chip->port, x    
703         if (xdma2 >= 0)                           
704                 sprintf(card->longname + strle    
705                                                   
706         return snd_card_register(card);           
707 }                                                 
708                                                   
709 #ifdef CONFIG_PNP                                 
710 static int snd_opl3sa2_pnp_detect(struct pnp_d    
711                                   const struct    
712 {                                                 
713         static int dev;                           
714         int err;                                  
715         struct snd_card *card;                    
716                                                   
717         if (pnp_device_is_isapnp(pdev))           
718                 return -ENOENT; /* we have ano    
719         for (; dev < SNDRV_CARDS; dev++) {        
720                 if (enable[dev] && isapnp[dev]    
721                         break;                    
722         }                                         
723         if (dev >= SNDRV_CARDS)                   
724                 return -ENODEV;                   
725                                                   
726         err = snd_opl3sa2_card_new(&pdev->dev,    
727         if (err < 0)                              
728                 return err;                       
729         err = snd_opl3sa2_pnp(dev, card->priva    
730         if (err < 0)                              
731                 return err;                       
732         err = snd_opl3sa2_probe(card, dev);       
733         if (err < 0)                              
734                 return err;                       
735         pnp_set_drvdata(pdev, card);              
736         dev++;                                    
737         return 0;                                 
738 }                                                 
739                                                   
740 #ifdef CONFIG_PM                                  
741 static int snd_opl3sa2_pnp_suspend(struct pnp_    
742 {                                                 
743         return snd_opl3sa2_suspend(pnp_get_drv    
744 }                                                 
745 static int snd_opl3sa2_pnp_resume(struct pnp_d    
746 {                                                 
747         return snd_opl3sa2_resume(pnp_get_drvd    
748 }                                                 
749 #endif                                            
750                                                   
751 static struct pnp_driver opl3sa2_pnp_driver =     
752         .name = "snd-opl3sa2-pnpbios",            
753         .id_table = snd_opl3sa2_pnpbiosids,       
754         .probe = snd_opl3sa2_pnp_detect,          
755 #ifdef CONFIG_PM                                  
756         .suspend = snd_opl3sa2_pnp_suspend,       
757         .resume = snd_opl3sa2_pnp_resume,         
758 #endif                                            
759 };                                                
760                                                   
761 static int snd_opl3sa2_pnp_cdetect(struct pnp_    
762                                    const struc    
763 {                                                 
764         static int dev;                           
765         struct pnp_dev *pdev;                     
766         int err;                                  
767         struct snd_card *card;                    
768                                                   
769         pdev = pnp_request_card_device(pcard,     
770         if (pdev == NULL) {                       
771                 dev_err(&pcard->card->dev, "ca    
772                            id->devs[0].id);       
773                 return -EBUSY;                    
774         }                                         
775         for (; dev < SNDRV_CARDS; dev++) {        
776                 if (enable[dev] && isapnp[dev]    
777                         break;                    
778         }                                         
779         if (dev >= SNDRV_CARDS)                   
780                 return -ENODEV;                   
781                                                   
782         err = snd_opl3sa2_card_new(&pdev->dev,    
783         if (err < 0)                              
784                 return err;                       
785         err = snd_opl3sa2_pnp(dev, card->priva    
786         if (err < 0)                              
787                 return err;                       
788         err = snd_opl3sa2_probe(card, dev);       
789         if (err < 0)                              
790                 return err;                       
791         pnp_set_card_drvdata(pcard, card);        
792         dev++;                                    
793         return 0;                                 
794 }                                                 
795                                                   
796 #ifdef CONFIG_PM                                  
797 static int snd_opl3sa2_pnp_csuspend(struct pnp    
798 {                                                 
799         return snd_opl3sa2_suspend(pnp_get_car    
800 }                                                 
801 static int snd_opl3sa2_pnp_cresume(struct pnp_    
802 {                                                 
803         return snd_opl3sa2_resume(pnp_get_card    
804 }                                                 
805 #endif                                            
806                                                   
807 static struct pnp_card_driver opl3sa2_pnpc_dri    
808         .flags = PNP_DRIVER_RES_DISABLE,          
809         .name = "snd-opl3sa2-cpnp",               
810         .id_table = snd_opl3sa2_pnpids,           
811         .probe = snd_opl3sa2_pnp_cdetect,         
812 #ifdef CONFIG_PM                                  
813         .suspend = snd_opl3sa2_pnp_csuspend,      
814         .resume = snd_opl3sa2_pnp_cresume,        
815 #endif                                            
816 };                                                
817 #endif /* CONFIG_PNP */                           
818                                                   
819 static int snd_opl3sa2_isa_match(struct device    
820                                  unsigned int     
821 {                                                 
822         if (!enable[dev])                         
823                 return 0;                         
824 #ifdef CONFIG_PNP                                 
825         if (isapnp[dev])                          
826                 return 0;                         
827 #endif                                            
828         if (port[dev] == SNDRV_AUTO_PORT) {       
829                 dev_err(pdev, "specify port\n"    
830                 return 0;                         
831         }                                         
832         if (wss_port[dev] == SNDRV_AUTO_PORT)     
833                 dev_err(pdev, "specify wss_por    
834                 return 0;                         
835         }                                         
836         if (fm_port[dev] == SNDRV_AUTO_PORT) {    
837                 dev_err(pdev, "specify fm_port    
838                 return 0;                         
839         }                                         
840         if (midi_port[dev] == SNDRV_AUTO_PORT)    
841                 dev_err(pdev, "specify midi_po    
842                 return 0;                         
843         }                                         
844         return 1;                                 
845 }                                                 
846                                                   
847 static int snd_opl3sa2_isa_probe(struct device    
848                                  unsigned int     
849 {                                                 
850         struct snd_card *card;                    
851         int err;                                  
852                                                   
853         err = snd_opl3sa2_card_new(pdev, dev,     
854         if (err < 0)                              
855                 return err;                       
856         err = snd_opl3sa2_probe(card, dev);       
857         if (err < 0)                              
858                 return err;                       
859         dev_set_drvdata(pdev, card);              
860         return 0;                                 
861 }                                                 
862                                                   
863 #ifdef CONFIG_PM                                  
864 static int snd_opl3sa2_isa_suspend(struct devi    
865                                    pm_message_    
866 {                                                 
867         return snd_opl3sa2_suspend(dev_get_drv    
868 }                                                 
869                                                   
870 static int snd_opl3sa2_isa_resume(struct devic    
871 {                                                 
872         return snd_opl3sa2_resume(dev_get_drvd    
873 }                                                 
874 #endif                                            
875                                                   
876 #define DEV_NAME "opl3sa2"                        
877                                                   
878 static struct isa_driver snd_opl3sa2_isa_drive    
879         .match          = snd_opl3sa2_isa_matc    
880         .probe          = snd_opl3sa2_isa_prob    
881 #ifdef CONFIG_PM                                  
882         .suspend        = snd_opl3sa2_isa_susp    
883         .resume         = snd_opl3sa2_isa_resu    
884 #endif                                            
885         .driver         = {                       
886                 .name   = DEV_NAME                
887         },                                        
888 };                                                
889                                                   
890 static int __init alsa_card_opl3sa2_init(void)    
891 {                                                 
892         int err;                                  
893                                                   
894         err = isa_register_driver(&snd_opl3sa2    
895 #ifdef CONFIG_PNP                                 
896         if (!err)                                 
897                 isa_registered = 1;               
898                                                   
899         err = pnp_register_driver(&opl3sa2_pnp    
900         if (!err)                                 
901                 pnp_registered = 1;               
902                                                   
903         err = pnp_register_card_driver(&opl3sa    
904         if (!err)                                 
905                 pnpc_registered = 1;              
906                                                   
907         if (isa_registered || pnp_registered)     
908                 err = 0;                          
909 #endif                                            
910         return err;                               
911 }                                                 
912                                                   
913 static void __exit alsa_card_opl3sa2_exit(void    
914 {                                                 
915 #ifdef CONFIG_PNP                                 
916         if (pnpc_registered)                      
917                 pnp_unregister_card_driver(&op    
918         if (pnp_registered)                       
919                 pnp_unregister_driver(&opl3sa2    
920         if (isa_registered)                       
921 #endif                                            
922                 isa_unregister_driver(&snd_opl    
923 }                                                 
924                                                   
925 module_init(alsa_card_opl3sa2_init)               
926 module_exit(alsa_card_opl3sa2_exit)               
927                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php