diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-04-03 07:20:49 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-05-11 10:55:55 -0400 |
commit | f9ab2b1c3ab5345f9003bf7ebc1eaa0f9b8cf99e (patch) | |
tree | 10645153733b7f71fe51a4485c9f997dd07a409f /sound/pci/ali5451 | |
parent | 51354ae3b8fdbeaf96e23ddf787432a38eba31f5 (diff) |
[ALSA] ali5451 - Code clean up, irq handler fix
- Clean up ali5451.c, following the standard coding style, unneeded codes
reduced, and removal of redundant variable initializations.
Hungarian notation isn't fixed yet ;)
- Fix irq handler to return IRQ_NONE properly for shared irqs.
Also check the hardware availability in irq handler to avoid possible
initialization races at loading the driver.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/ali5451')
-rw-r--r-- | sound/pci/ali5451/ali5451.c | 865 |
1 files changed, 420 insertions, 445 deletions
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index cd2fe374744c..e1ed59549c50 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -69,10 +69,10 @@ module_param(enable, bool, 0444); | |||
69 | * Debug part definitions | 69 | * Debug part definitions |
70 | */ | 70 | */ |
71 | 71 | ||
72 | //#define ALI_DEBUG | 72 | /* #define ALI_DEBUG */ |
73 | 73 | ||
74 | #ifdef ALI_DEBUG | 74 | #ifdef ALI_DEBUG |
75 | #define snd_ali_printk(format, args...) printk(format, ##args); | 75 | #define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args); |
76 | #else | 76 | #else |
77 | #define snd_ali_printk(format, args...) | 77 | #define snd_ali_printk(format, args...) |
78 | #endif | 78 | #endif |
@@ -105,10 +105,10 @@ module_param(enable, bool, 0444); | |||
105 | * Direct Registers | 105 | * Direct Registers |
106 | */ | 106 | */ |
107 | 107 | ||
108 | #define ALI_LEGACY_DMAR0 0x00 // ADR0 | 108 | #define ALI_LEGACY_DMAR0 0x00 /* ADR0 */ |
109 | #define ALI_LEGACY_DMAR4 0x04 // CNT0 | 109 | #define ALI_LEGACY_DMAR4 0x04 /* CNT0 */ |
110 | #define ALI_LEGACY_DMAR11 0x0b // MOD | 110 | #define ALI_LEGACY_DMAR11 0x0b /* MOD */ |
111 | #define ALI_LEGACY_DMAR15 0x0f // MMR | 111 | #define ALI_LEGACY_DMAR15 0x0f /* MMR */ |
112 | #define ALI_MPUR0 0x20 | 112 | #define ALI_MPUR0 0x20 |
113 | #define ALI_MPUR1 0x21 | 113 | #define ALI_MPUR1 0x21 |
114 | #define ALI_MPUR2 0x22 | 114 | #define ALI_MPUR2 0x22 |
@@ -175,7 +175,7 @@ struct snd_ali; | |||
175 | struct snd_ali_voice; | 175 | struct snd_ali_voice; |
176 | 176 | ||
177 | struct snd_ali_channel_control { | 177 | struct snd_ali_channel_control { |
178 | // register data | 178 | /* register data */ |
179 | struct REGDATA { | 179 | struct REGDATA { |
180 | unsigned int start; | 180 | unsigned int start; |
181 | unsigned int stop; | 181 | unsigned int stop; |
@@ -183,7 +183,7 @@ struct snd_ali_channel_control { | |||
183 | unsigned int ainten; | 183 | unsigned int ainten; |
184 | } data; | 184 | } data; |
185 | 185 | ||
186 | // register addresses | 186 | /* register addresses */ |
187 | struct REGS { | 187 | struct REGS { |
188 | unsigned int start; | 188 | unsigned int start; |
189 | unsigned int stop; | 189 | unsigned int stop; |
@@ -197,19 +197,18 @@ struct snd_ali_channel_control { | |||
197 | 197 | ||
198 | struct snd_ali_voice { | 198 | struct snd_ali_voice { |
199 | unsigned int number; | 199 | unsigned int number; |
200 | unsigned int use: 1, | 200 | unsigned int use :1, |
201 | pcm: 1, | 201 | pcm :1, |
202 | midi: 1, | 202 | midi :1, |
203 | mode: 1, | 203 | mode :1, |
204 | synth: 1; | 204 | synth :1, |
205 | running :1; | ||
205 | 206 | ||
206 | /* PCM data */ | 207 | /* PCM data */ |
207 | struct snd_ali *codec; | 208 | struct snd_ali *codec; |
208 | struct snd_pcm_substream *substream; | 209 | struct snd_pcm_substream *substream; |
209 | struct snd_ali_voice *extra; | 210 | struct snd_ali_voice *extra; |
210 | 211 | ||
211 | unsigned int running: 1; | ||
212 | |||
213 | int eso; /* final ESO value for channel */ | 212 | int eso; /* final ESO value for channel */ |
214 | int count; /* runtime->period_size */ | 213 | int count; /* runtime->period_size */ |
215 | 214 | ||
@@ -231,14 +230,12 @@ struct snd_alidev { | |||
231 | }; | 230 | }; |
232 | 231 | ||
233 | 232 | ||
234 | #ifdef CONFIG_PM | ||
235 | #define ALI_GLOBAL_REGS 56 | 233 | #define ALI_GLOBAL_REGS 56 |
236 | #define ALI_CHANNEL_REGS 8 | 234 | #define ALI_CHANNEL_REGS 8 |
237 | struct snd_ali_image { | 235 | struct snd_ali_image { |
238 | unsigned long regs[ALI_GLOBAL_REGS]; | 236 | u32 regs[ALI_GLOBAL_REGS]; |
239 | unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; | 237 | u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; |
240 | }; | 238 | }; |
241 | #endif | ||
242 | 239 | ||
243 | 240 | ||
244 | struct snd_ali { | 241 | struct snd_ali { |
@@ -246,8 +243,8 @@ struct snd_ali { | |||
246 | unsigned long port; | 243 | unsigned long port; |
247 | unsigned char revision; | 244 | unsigned char revision; |
248 | 245 | ||
249 | unsigned int hw_initialized: 1; | 246 | unsigned int hw_initialized :1; |
250 | unsigned int spdif_support: 1; | 247 | unsigned int spdif_support :1; |
251 | 248 | ||
252 | struct pci_dev *pci; | 249 | struct pci_dev *pci; |
253 | struct pci_dev *pci_m1533; | 250 | struct pci_dev *pci_m1533; |
@@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids); | |||
287 | 284 | ||
288 | static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int); | 285 | static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int); |
289 | static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short); | 286 | static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short); |
290 | static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short); | 287 | static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, |
291 | 288 | unsigned short); | |
292 | /* | ||
293 | * Debug Part | ||
294 | */ | ||
295 | |||
296 | #ifdef ALI_DEBUG | ||
297 | |||
298 | static void ali_read_regs(struct snd_ali *codec, int channel) | ||
299 | { | ||
300 | int i,j; | ||
301 | unsigned int dwVal; | ||
302 | |||
303 | printk("channel %d registers map:\n", channel); | ||
304 | outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR)); | ||
305 | |||
306 | printk(" "); | ||
307 | for(j=0;j<8;j++) | ||
308 | printk("%2.2x ", j*4); | ||
309 | printk("\n"); | ||
310 | |||
311 | for (i=0; i<=0xf8/4;i++) { | ||
312 | if(i%8 == 0) | ||
313 | printk("%2.2x ", (i*4/0x10)*0x10); | ||
314 | dwVal = inl(ALI_REG(codec,i*4)); | ||
315 | printk("%8.8x ", dwVal); | ||
316 | if ((i+1)%8 == 0) | ||
317 | printk("\n"); | ||
318 | } | ||
319 | printk("\n"); | ||
320 | } | ||
321 | static void ali_read_cfg(unsigned int vendor, unsigned deviceid) | ||
322 | { | ||
323 | unsigned int dwVal; | ||
324 | struct pci_dev *pci_dev; | ||
325 | int i,j; | ||
326 | |||
327 | pci_dev = pci_get_device(vendor, deviceid, NULL); | ||
328 | if (pci_dev == NULL) | ||
329 | return ; | ||
330 | |||
331 | printk("\nM%x PCI CFG\n", deviceid); | ||
332 | printk(" "); | ||
333 | for(j=0;j<8;j++) | ||
334 | printk("%d ",j); | ||
335 | printk("\n"); | ||
336 | |||
337 | for(i=0;i<8;i++) { | ||
338 | printk("%d ",i); | ||
339 | for(j=0;j<8;j++) | ||
340 | { | ||
341 | pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal); | ||
342 | printk("%8.8x ", dwVal); | ||
343 | } | ||
344 | printk("\n"); | ||
345 | } | ||
346 | pci_dev_put(pci_dev); | ||
347 | } | ||
348 | static void ali_read_ac97regs(struct snd_ali *codec, int secondary) | ||
349 | { | ||
350 | unsigned short i,j; | ||
351 | unsigned short wVal; | ||
352 | |||
353 | printk("\ncodec %d registers map:\n", secondary); | ||
354 | |||
355 | printk(" "); | ||
356 | for(j=0;j<8;j++) | ||
357 | printk("%2.2x ",j*2); | ||
358 | printk("\n"); | ||
359 | |||
360 | for (i=0; i<64;i++) { | ||
361 | if(i%8 == 0) | ||
362 | printk("%2.2x ", (i/8)*0x10); | ||
363 | wVal = snd_ali_codec_peek(codec, secondary, i*2); | ||
364 | printk("%4.4x ", wVal); | ||
365 | if ((i+1)%8 == 0) | ||
366 | printk("\n"); | ||
367 | } | ||
368 | printk("\n"); | ||
369 | } | ||
370 | |||
371 | #endif | ||
372 | 289 | ||
373 | /* | 290 | /* |
374 | * AC97 ACCESS | 291 | * AC97 ACCESS |
375 | */ | 292 | */ |
376 | 293 | ||
377 | static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec, | 294 | static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec, |
378 | unsigned int port ) | 295 | unsigned int port) |
379 | { | 296 | { |
380 | return (unsigned int)inl(ALI_REG(codec, port)); | 297 | return (unsigned int)inl(ALI_REG(codec, port)); |
381 | } | 298 | } |
382 | 299 | ||
383 | static inline void snd_ali_5451_poke( struct snd_ali *codec, | 300 | static inline void snd_ali_5451_poke(struct snd_ali *codec, |
384 | unsigned int port, | 301 | unsigned int port, |
385 | unsigned int val ) | 302 | unsigned int val) |
386 | { | 303 | { |
387 | outl((unsigned int)val, ALI_REG(codec, port)); | 304 | outl((unsigned int)val, ALI_REG(codec, port)); |
388 | } | 305 | } |
389 | 306 | ||
390 | static int snd_ali_codec_ready( struct snd_ali *codec, | 307 | static int snd_ali_codec_ready(struct snd_ali *codec, |
391 | unsigned int port ) | 308 | unsigned int port) |
392 | { | 309 | { |
393 | unsigned long end_time; | 310 | unsigned long end_time; |
394 | unsigned int res; | 311 | unsigned int res; |
@@ -396,7 +313,7 @@ static int snd_ali_codec_ready( struct snd_ali *codec, | |||
396 | end_time = jiffies + msecs_to_jiffies(250); | 313 | end_time = jiffies + msecs_to_jiffies(250); |
397 | do { | 314 | do { |
398 | res = snd_ali_5451_peek(codec,port); | 315 | res = snd_ali_5451_peek(codec,port); |
399 | if (! (res & 0x8000)) | 316 | if (!(res & 0x8000)) |
400 | return 0; | 317 | return 0; |
401 | schedule_timeout_uninterruptible(1); | 318 | schedule_timeout_uninterruptible(1); |
402 | } while (time_after_eq(end_time, jiffies)); | 319 | } while (time_after_eq(end_time, jiffies)); |
@@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec) | |||
425 | } | 342 | } |
426 | 343 | ||
427 | static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, | 344 | static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, |
428 | unsigned short reg, | 345 | unsigned short reg, |
429 | unsigned short val) | 346 | unsigned short val) |
430 | { | 347 | { |
431 | unsigned int dwVal = 0; | 348 | unsigned int dwVal; |
432 | unsigned int port = 0; | 349 | unsigned int port; |
433 | 350 | ||
434 | if (reg >= 0x80) { | 351 | if (reg >= 0x80) { |
435 | snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg); | 352 | snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg); |
@@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, | |||
445 | 362 | ||
446 | dwVal = (unsigned int) (reg & 0xff); | 363 | dwVal = (unsigned int) (reg & 0xff); |
447 | dwVal |= 0x8000 | (val << 16); | 364 | dwVal |= 0x8000 | (val << 16); |
448 | if (secondary) dwVal |= 0x0080; | 365 | if (secondary) |
449 | if (codec->revision == ALI_5451_V02) dwVal |= 0x0100; | 366 | dwVal |= 0x0080; |
367 | if (codec->revision == ALI_5451_V02) | ||
368 | dwVal |= 0x0100; | ||
450 | 369 | ||
451 | snd_ali_5451_poke(codec,port,dwVal); | 370 | snd_ali_5451_poke(codec, port, dwVal); |
452 | 371 | ||
453 | return ; | 372 | return ; |
454 | } | 373 | } |
455 | 374 | ||
456 | static unsigned short snd_ali_codec_peek( struct snd_ali *codec, | 375 | static unsigned short snd_ali_codec_peek(struct snd_ali *codec, |
457 | int secondary, | 376 | int secondary, |
458 | unsigned short reg) | 377 | unsigned short reg) |
459 | { | 378 | { |
460 | unsigned int dwVal = 0; | 379 | unsigned int dwVal; |
461 | unsigned int port = 0; | 380 | unsigned int port; |
462 | 381 | ||
463 | if (reg >= 0x80) { | 382 | if (reg >= 0x80) { |
464 | snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg); | 383 | snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg); |
@@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, | |||
474 | 393 | ||
475 | dwVal = (unsigned int) (reg & 0xff); | 394 | dwVal = (unsigned int) (reg & 0xff); |
476 | dwVal |= 0x8000; /* bit 15*/ | 395 | dwVal |= 0x8000; /* bit 15*/ |
477 | if (secondary) dwVal |= 0x0080; | 396 | if (secondary) |
397 | dwVal |= 0x0080; | ||
478 | 398 | ||
479 | snd_ali_5451_poke(codec, port, dwVal); | 399 | snd_ali_5451_poke(codec, port, dwVal); |
480 | 400 | ||
@@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, | |||
483 | if (snd_ali_codec_ready(codec, port) < 0) | 403 | if (snd_ali_codec_ready(codec, port) < 0) |
484 | return ~0; | 404 | return ~0; |
485 | 405 | ||
486 | return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16; | 406 | return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16; |
487 | } | 407 | } |
488 | 408 | ||
489 | static void snd_ali_codec_write(struct snd_ac97 *ac97, | 409 | static void snd_ali_codec_write(struct snd_ac97 *ac97, |
@@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, | |||
493 | struct snd_ali *codec = ac97->private_data; | 413 | struct snd_ali *codec = ac97->private_data; |
494 | 414 | ||
495 | snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val); | 415 | snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val); |
496 | if(reg == AC97_GPIO_STATUS) { | 416 | if (reg == AC97_GPIO_STATUS) { |
497 | outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE, | 417 | outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE, |
498 | ALI_REG(codec, ALI_AC97_GPIO)); | 418 | ALI_REG(codec, ALI_AC97_GPIO)); |
499 | return; | 419 | return; |
500 | } | 420 | } |
501 | snd_ali_codec_poke(codec, ac97->num, reg, val); | 421 | snd_ali_codec_poke(codec, ac97->num, reg, val); |
@@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, | |||
503 | } | 423 | } |
504 | 424 | ||
505 | 425 | ||
506 | static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg) | 426 | static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, |
427 | unsigned short reg) | ||
507 | { | 428 | { |
508 | struct snd_ali *codec = ac97->private_data; | 429 | struct snd_ali *codec = ac97->private_data; |
509 | 430 | ||
510 | snd_ali_printk("codec_read reg=%xh.\n", reg); | 431 | snd_ali_printk("codec_read reg=%xh.\n", reg); |
511 | return (snd_ali_codec_peek(codec, ac97->num, reg)); | 432 | return snd_ali_codec_peek(codec, ac97->num, reg); |
512 | } | 433 | } |
513 | 434 | ||
514 | /* | 435 | /* |
@@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r | |||
517 | 438 | ||
518 | static int snd_ali_reset_5451(struct snd_ali *codec) | 439 | static int snd_ali_reset_5451(struct snd_ali *codec) |
519 | { | 440 | { |
520 | struct pci_dev *pci_dev = NULL; | 441 | struct pci_dev *pci_dev; |
521 | unsigned short wCount, wReg; | 442 | unsigned short wCount, wReg; |
522 | unsigned int dwVal; | 443 | unsigned int dwVal; |
523 | 444 | ||
524 | if ((pci_dev = codec->pci_m1533) != NULL) { | 445 | pci_dev = codec->pci_m1533; |
446 | if (pci_dev) { | ||
525 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); | 447 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); |
526 | pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); | 448 | pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); |
527 | udelay(5000); | 449 | udelay(5000); |
@@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec) | |||
541 | wCount = 200; | 463 | wCount = 200; |
542 | while(wCount--) { | 464 | while(wCount--) { |
543 | wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); | 465 | wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); |
544 | if((wReg & 0x000f) == 0x000f) | 466 | if ((wReg & 0x000f) == 0x000f) |
545 | return 0; | 467 | return 0; |
546 | udelay(5000); | 468 | udelay(5000); |
547 | } | 469 | } |
@@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec) | |||
555 | 477 | ||
556 | static int snd_ali_reset_codec(struct snd_ali *codec) | 478 | static int snd_ali_reset_codec(struct snd_ali *codec) |
557 | { | 479 | { |
558 | struct pci_dev *pci_dev = NULL; | 480 | struct pci_dev *pci_dev; |
559 | unsigned char bVal = 0; | 481 | unsigned char bVal; |
560 | unsigned int dwVal; | 482 | unsigned int dwVal; |
561 | unsigned short wCount, wReg; | 483 | unsigned short wCount, wReg; |
562 | 484 | ||
@@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec) | |||
579 | udelay(15000); | 501 | udelay(15000); |
580 | 502 | ||
581 | wCount = 200; | 503 | wCount = 200; |
582 | while(wCount--) { | 504 | while (wCount--) { |
583 | wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN); | 505 | wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN); |
584 | if((wReg & 0x000f) == 0x000f) | 506 | if ((wReg & 0x000f) == 0x000f) |
585 | return 0; | 507 | return 0; |
586 | udelay(5000); | 508 | udelay(5000); |
587 | } | 509 | } |
@@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec) | |||
594 | * ALI 5451 Controller | 516 | * ALI 5451 Controller |
595 | */ | 517 | */ |
596 | 518 | ||
597 | static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel) | 519 | static void snd_ali_enable_special_channel(struct snd_ali *codec, |
520 | unsigned int channel) | ||
598 | { | 521 | { |
599 | unsigned long dwVal = 0; | 522 | unsigned long dwVal; |
600 | 523 | ||
601 | dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 524 | dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
602 | dwVal |= 1 << (channel & 0x0000001f); | 525 | dwVal |= 1 << (channel & 0x0000001f); |
603 | outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 526 | outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
604 | } | 527 | } |
605 | 528 | ||
606 | static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel) | 529 | static void snd_ali_disable_special_channel(struct snd_ali *codec, |
530 | unsigned int channel) | ||
607 | { | 531 | { |
608 | unsigned long dwVal = 0; | 532 | unsigned long dwVal; |
609 | 533 | ||
610 | dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 534 | dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
611 | dwVal &= ~(1 << (channel & 0x0000001f)); | 535 | dwVal &= ~(1 << (channel & 0x0000001f)); |
612 | outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); | 536 | outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
613 | } | 537 | } |
614 | 538 | ||
615 | static void snd_ali_enable_address_interrupt(struct snd_ali * codec) | 539 | static void snd_ali_enable_address_interrupt(struct snd_ali *codec) |
616 | { | 540 | { |
617 | unsigned int gc; | 541 | unsigned int gc; |
618 | 542 | ||
@@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec) | |||
622 | outl( gc, ALI_REG(codec, ALI_GC_CIR)); | 546 | outl( gc, ALI_REG(codec, ALI_GC_CIR)); |
623 | } | 547 | } |
624 | 548 | ||
625 | static void snd_ali_disable_address_interrupt(struct snd_ali * codec) | 549 | static void snd_ali_disable_address_interrupt(struct snd_ali *codec) |
626 | { | 550 | { |
627 | unsigned int gc; | 551 | unsigned int gc; |
628 | 552 | ||
@@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec) | |||
632 | outl(gc, ALI_REG(codec, ALI_GC_CIR)); | 556 | outl(gc, ALI_REG(codec, ALI_GC_CIR)); |
633 | } | 557 | } |
634 | 558 | ||
635 | #if 0 // not used | 559 | #if 0 /* not used */ |
636 | static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel) | 560 | static void snd_ali_enable_voice_irq(struct snd_ali *codec, |
561 | unsigned int channel) | ||
637 | { | 562 | { |
638 | unsigned int mask; | 563 | unsigned int mask; |
639 | struct snd_ali_channel_control *pchregs = &(codec->chregs); | 564 | struct snd_ali_channel_control *pchregs = &(codec->chregs); |
@@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel | |||
641 | snd_ali_printk("enable_voice_irq channel=%d\n",channel); | 566 | snd_ali_printk("enable_voice_irq channel=%d\n",channel); |
642 | 567 | ||
643 | mask = 1 << (channel & 0x1f); | 568 | mask = 1 << (channel & 0x1f); |
644 | pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); | 569 | pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); |
645 | pchregs->data.ainten |= mask; | 570 | pchregs->data.ainten |= mask; |
646 | outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); | 571 | outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); |
647 | } | 572 | } |
648 | #endif | 573 | #endif |
649 | 574 | ||
650 | static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel) | 575 | static void snd_ali_disable_voice_irq(struct snd_ali *codec, |
576 | unsigned int channel) | ||
651 | { | 577 | { |
652 | unsigned int mask; | 578 | unsigned int mask; |
653 | struct snd_ali_channel_control *pchregs = &(codec->chregs); | 579 | struct snd_ali_channel_control *pchregs = &(codec->chregs); |
@@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe | |||
655 | snd_ali_printk("disable_voice_irq channel=%d\n",channel); | 581 | snd_ali_printk("disable_voice_irq channel=%d\n",channel); |
656 | 582 | ||
657 | mask = 1 << (channel & 0x1f); | 583 | mask = 1 << (channel & 0x1f); |
658 | pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); | 584 | pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); |
659 | pchregs->data.ainten &= ~mask; | 585 | pchregs->data.ainten &= ~mask; |
660 | outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); | 586 | outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); |
661 | } | 587 | } |
662 | 588 | ||
663 | static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) | 589 | static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) |
@@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) | |||
665 | unsigned int idx = channel & 0x1f; | 591 | unsigned int idx = channel & 0x1f; |
666 | 592 | ||
667 | if (codec->synth.chcnt >= ALI_CHANNELS){ | 593 | if (codec->synth.chcnt >= ALI_CHANNELS){ |
668 | snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n"); | 594 | snd_printk(KERN_ERR |
595 | "ali_alloc_pcm_channel: no free channels.\n"); | ||
669 | return -1; | 596 | return -1; |
670 | } | 597 | } |
671 | 598 | ||
@@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec) | |||
685 | 612 | ||
686 | snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm"); | 613 | snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm"); |
687 | 614 | ||
688 | // recording | 615 | /* recording */ |
689 | if (rec) { | 616 | if (rec) { |
690 | if (codec->spdif_support && | 617 | if (codec->spdif_support && |
691 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT)) | 618 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & |
619 | ALI_SPDIF_IN_SUPPORT)) | ||
692 | idx = ALI_SPDIF_IN_CHANNEL; | 620 | idx = ALI_SPDIF_IN_CHANNEL; |
693 | else | 621 | else |
694 | idx = ALI_PCM_IN_CHANNEL; | 622 | idx = ALI_PCM_IN_CHANNEL; |
695 | 623 | ||
696 | if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { | 624 | result = snd_ali_alloc_pcm_channel(codec, idx); |
625 | if (result >= 0) | ||
697 | return result; | 626 | return result; |
698 | } else { | 627 | else { |
699 | snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n"); | 628 | snd_printk(KERN_ERR "ali_find_free_channel: " |
629 | "record channel is busy now.\n"); | ||
700 | return -1; | 630 | return -1; |
701 | } | 631 | } |
702 | } | 632 | } |
703 | 633 | ||
704 | //playback... | 634 | /* playback... */ |
705 | if (codec->spdif_support && | 635 | if (codec->spdif_support && |
706 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) { | 636 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & |
637 | ALI_SPDIF_OUT_CH_ENABLE)) { | ||
707 | idx = ALI_SPDIF_OUT_CHANNEL; | 638 | idx = ALI_SPDIF_OUT_CHANNEL; |
708 | if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { | 639 | result = snd_ali_alloc_pcm_channel(codec, idx); |
640 | if (result >= 0) | ||
709 | return result; | 641 | return result; |
710 | } else { | 642 | else |
711 | snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n"); | 643 | snd_printk(KERN_ERR "ali_find_free_channel: " |
712 | } | 644 | "S/PDIF out channel is in busy now.\n"); |
713 | } | 645 | } |
714 | 646 | ||
715 | for (idx = 0; idx < ALI_CHANNELS; idx++) { | 647 | for (idx = 0; idx < ALI_CHANNELS; idx++) { |
716 | if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) | 648 | result = snd_ali_alloc_pcm_channel(codec, idx); |
649 | if (result >= 0) | ||
717 | return result; | 650 | return result; |
718 | } | 651 | } |
719 | snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n"); | 652 | snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n"); |
@@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) | |||
730 | return; | 663 | return; |
731 | 664 | ||
732 | if (!(codec->synth.chmap & (1 << idx))) { | 665 | if (!(codec->synth.chmap & (1 << idx))) { |
733 | snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel); | 666 | snd_printk(KERN_ERR "ali_free_channel_pcm: " |
667 | "channel %d is not in use.\n", channel); | ||
734 | return; | 668 | return; |
735 | } else { | 669 | } else { |
736 | codec->synth.chmap &= ~(1 << idx); | 670 | codec->synth.chmap &= ~(1 << idx); |
@@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) | |||
738 | } | 672 | } |
739 | } | 673 | } |
740 | 674 | ||
741 | #if 0 // not used | 675 | #if 0 /* not used */ |
742 | static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) | 676 | static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel) |
743 | { | 677 | { |
744 | unsigned int mask = 1 << (channel & 0x1f); | 678 | unsigned int mask = 1 << (channel & 0x1f); |
745 | 679 | ||
@@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) | |||
748 | } | 682 | } |
749 | #endif | 683 | #endif |
750 | 684 | ||
751 | static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel) | 685 | static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel) |
752 | { | 686 | { |
753 | unsigned int mask = 1 << (channel & 0x1f); | 687 | unsigned int mask = 1 << (channel & 0x1f); |
754 | 688 | ||
@@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval) | |||
768 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); | 702 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); |
769 | 703 | ||
770 | while (currenttimer < begintimer + interval) { | 704 | while (currenttimer < begintimer + interval) { |
771 | if(snd_ali_stimer_ready(codec) < 0) | 705 | if (snd_ali_stimer_ready(codec) < 0) |
772 | break; | 706 | break; |
773 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); | 707 | currenttimer = inl(ALI_REG(codec, ALI_STIMER)); |
708 | cpu_relax(); | ||
774 | } | 709 | } |
775 | } | 710 | } |
776 | 711 | ||
777 | static void snd_ali_detect_spdif_rate(struct snd_ali *codec) | 712 | static void snd_ali_detect_spdif_rate(struct snd_ali *codec) |
778 | { | 713 | { |
779 | u16 wval = 0; | 714 | u16 wval; |
780 | u16 count = 0; | 715 | u16 count = 0; |
781 | u8 bval = 0, R1 = 0, R2 = 0; | 716 | u8 bval, R1 = 0, R2; |
782 | 717 | ||
783 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 718 | bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); |
784 | bval |= 0x1F; | 719 | bval |= 0x1F; |
785 | outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 720 | outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1)); |
786 | 721 | ||
787 | while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) { | 722 | while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) { |
788 | count ++; | 723 | count ++; |
789 | snd_ali_delay(codec, 6); | 724 | snd_ali_delay(codec, 6); |
790 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 725 | bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); |
791 | R1 = bval & 0x1F; | 726 | R1 = bval & 0x1F; |
792 | } | 727 | } |
793 | 728 | ||
@@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) | |||
801 | snd_ali_delay(codec, 6); | 736 | snd_ali_delay(codec, 6); |
802 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); | 737 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); |
803 | R2 = bval & 0x1F; | 738 | R2 = bval & 0x1F; |
804 | if (R2 != R1) R1 = R2; else break; | 739 | if (R2 != R1) |
740 | R1 = R2; | ||
741 | else | ||
742 | break; | ||
805 | } | 743 | } |
806 | 744 | ||
807 | if (count > 50000) { | 745 | if (count > 50000) { |
@@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) | |||
810 | } | 748 | } |
811 | 749 | ||
812 | if (R2 >= 0x0b && R2 <= 0x0e) { | 750 | if (R2 >= 0x0b && R2 <= 0x0e) { |
813 | wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 751 | wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
814 | wval &= 0xE0F0; | 752 | wval &= 0xe0f0; |
815 | wval |= (u16)0x09 << 8 | (u16)0x05; | 753 | wval |= (0x09 << 8) | 0x05; |
816 | outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 754 | outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
817 | 755 | ||
818 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; | 756 | bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0; |
819 | outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3)); | 757 | outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3)); |
820 | } else if (R2 == 0x12) { | 758 | } else if (R2 == 0x12) { |
821 | wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 759 | wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
822 | wval &= 0xE0F0; | 760 | wval &= 0xe0f0; |
823 | wval |= (u16)0x0E << 8 | (u16)0x08; | 761 | wval |= (0x0e << 8) | 0x08; |
824 | outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); | 762 | outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); |
825 | 763 | ||
826 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; | 764 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0; |
827 | outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3)); | 765 | outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3)); |
828 | } | 766 | } |
829 | } | 767 | } |
830 | 768 | ||
831 | static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec) | 769 | static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec) |
832 | { | 770 | { |
833 | u32 dwRate = 0; | 771 | u32 dwRate; |
834 | u8 bval = 0; | 772 | u8 bval; |
835 | 773 | ||
836 | bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL)); | 774 | bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); |
837 | bval &= 0x7F; | 775 | bval &= 0x7f; |
838 | bval |= 0x40; | 776 | bval |= 0x40; |
839 | outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL)); | 777 | outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL)); |
840 | 778 | ||
841 | snd_ali_detect_spdif_rate(codec); | 779 | snd_ali_detect_spdif_rate(codec); |
842 | 780 | ||
843 | bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)); | 781 | bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)); |
844 | bval &= 0x0F; | 782 | bval &= 0x0f; |
845 | 783 | ||
846 | if (bval == 0) dwRate = 44100; | 784 | switch (bval) { |
847 | if (bval == 1) dwRate = 48000; | 785 | case 0: dwRate = 44100; break; |
848 | if (bval == 2) dwRate = 32000; | 786 | case 1: dwRate = 48000; break; |
787 | case 2: dwRate = 32000; break; | ||
788 | default: dwRate = 0; break; | ||
789 | } | ||
849 | 790 | ||
850 | return dwRate; | 791 | return dwRate; |
851 | } | 792 | } |
@@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec) | |||
880 | static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate) | 821 | static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate) |
881 | { | 822 | { |
882 | unsigned char bVal; | 823 | unsigned char bVal; |
883 | unsigned int dwRate = 0; | 824 | unsigned int dwRate; |
884 | 825 | ||
885 | if (rate == 32000) dwRate = 0x300; | 826 | switch (rate) { |
886 | if (rate == 44100) dwRate = 0; | 827 | case 32000: dwRate = 0x300; break; |
887 | if (rate == 48000) dwRate = 0x200; | 828 | case 48000: dwRate = 0x200; break; |
829 | default: dwRate = 0; break; | ||
830 | } | ||
888 | 831 | ||
889 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); | 832 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); |
890 | bVal &= (unsigned char)(~(1<<6)); | 833 | bVal &= (unsigned char)(~(1<<6)); |
891 | 834 | ||
892 | bVal |= 0x80; //select right | 835 | bVal |= 0x80; /* select right */ |
893 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); | 836 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); |
894 | outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2)); | 837 | outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2)); |
895 | 838 | ||
896 | bVal &= (~0x80); //select left | 839 | bVal &= ~0x80; /* select left */ |
897 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); | 840 | outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); |
898 | outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2)); | 841 | outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2)); |
899 | } | 842 | } |
@@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) | |||
902 | { | 845 | { |
903 | unsigned short wVal; | 846 | unsigned short wVal; |
904 | unsigned char bVal; | 847 | unsigned char bVal; |
905 | 848 | struct pci_dev *pci_dev; | |
906 | struct pci_dev *pci_dev = NULL; | ||
907 | 849 | ||
908 | pci_dev = codec->pci_m1533; | 850 | pci_dev = codec->pci_m1533; |
909 | if (pci_dev == NULL) | 851 | if (pci_dev == NULL) |
@@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) | |||
926 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); | 868 | bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); |
927 | outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL)); | 869 | outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL)); |
928 | 870 | ||
929 | { | 871 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
930 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 872 | wVal |= ALI_SPDIF_OUT_SEL_PCM; |
931 | wVal |= ALI_SPDIF_OUT_SEL_PCM; | 873 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
932 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 874 | snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); |
933 | snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); | ||
934 | } | ||
935 | } | 875 | } |
936 | 876 | ||
937 | static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) | 877 | static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) |
938 | { | 878 | { |
939 | unsigned short wVal = 0; | 879 | unsigned short wVal; |
940 | 880 | ||
941 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 881 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
942 | wVal &= ~ALI_SPDIF_OUT_SEL_PCM; | 882 | wVal &= ~ALI_SPDIF_OUT_SEL_PCM; |
@@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) | |||
949 | wVal &= (~0x0002); | 889 | wVal &= (~0x0002); |
950 | outw(wVal, ALI_REG(codec, ALI_SPDIF_CS)); | 890 | outw(wVal, ALI_REG(codec, ALI_SPDIF_CS)); |
951 | */ | 891 | */ |
952 | snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); | 892 | snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); |
953 | } | 893 | } |
954 | 894 | ||
955 | static void snd_ali_disable_spdif_chnout(struct snd_ali *codec) | 895 | static void snd_ali_disable_spdif_chnout(struct snd_ali *codec) |
956 | { | 896 | { |
957 | unsigned short wVal = 0; | 897 | unsigned short wVal; |
898 | |||
958 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 899 | wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
959 | wVal |= ALI_SPDIF_OUT_SEL_PCM; | 900 | wVal |= ALI_SPDIF_OUT_SEL_PCM; |
960 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); | 901 | outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); |
@@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec) | |||
972 | snd_ali_disable_spdif_chnout(codec); | 913 | snd_ali_disable_spdif_chnout(codec); |
973 | } | 914 | } |
974 | 915 | ||
975 | static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | 916 | static void snd_ali_update_ptr(struct snd_ali *codec, int channel) |
976 | { | 917 | { |
977 | struct snd_ali_voice *pvoice = NULL; | 918 | struct snd_ali_voice *pvoice; |
978 | struct snd_pcm_runtime *runtime; | 919 | struct snd_pcm_runtime *runtime; |
979 | struct snd_ali_channel_control *pchregs = NULL; | 920 | struct snd_ali_channel_control *pchregs; |
980 | unsigned int old, mask; | 921 | unsigned int old, mask; |
981 | #ifdef ALI_DEBUG | 922 | #ifdef ALI_DEBUG |
982 | unsigned int temp, cspf; | 923 | unsigned int temp, cspf; |
@@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | |||
984 | 925 | ||
985 | pchregs = &(codec->chregs); | 926 | pchregs = &(codec->chregs); |
986 | 927 | ||
987 | // check if interrupt occurred for channel | 928 | /* check if interrupt occurred for channel */ |
988 | old = pchregs->data.aint; | 929 | old = pchregs->data.aint; |
989 | mask = ((unsigned int) 1L) << (channel & 0x1f); | 930 | mask = 1U << (channel & 0x1f); |
990 | 931 | ||
991 | if (!(old & mask)) | 932 | if (!(old & mask)) |
992 | return; | 933 | return; |
@@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | |||
1005 | cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask; | 946 | cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask; |
1006 | #endif | 947 | #endif |
1007 | if (pvoice->running) { | 948 | if (pvoice->running) { |
1008 | snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf); | 949 | snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n", |
950 | (u16)temp, cspf); | ||
1009 | spin_unlock(&codec->reg_lock); | 951 | spin_unlock(&codec->reg_lock); |
1010 | snd_pcm_period_elapsed(pvoice->substream); | 952 | snd_pcm_period_elapsed(pvoice->substream); |
1011 | spin_lock(&codec->reg_lock); | 953 | spin_lock(&codec->reg_lock); |
@@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) | |||
1027 | pchregs->data.aint = old & (~mask); | 969 | pchregs->data.aint = old & (~mask); |
1028 | } | 970 | } |
1029 | 971 | ||
1030 | static void snd_ali_interrupt(struct snd_ali * codec) | 972 | static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) |
1031 | { | 973 | { |
974 | struct snd_ali *codec = dev_id; | ||
1032 | int channel; | 975 | int channel; |
1033 | unsigned int audio_int; | 976 | unsigned int audio_int; |
1034 | struct snd_ali_channel_control *pchregs = NULL; | 977 | struct snd_ali_channel_control *pchregs; |
1035 | pchregs = &(codec->chregs); | 978 | |
979 | if (codec == NULL || !codec->hw_initialized) | ||
980 | return IRQ_NONE; | ||
1036 | 981 | ||
1037 | audio_int = inl(ALI_REG(codec, ALI_MISCINT)); | 982 | audio_int = inl(ALI_REG(codec, ALI_MISCINT)); |
983 | if (!audio_int) | ||
984 | return IRQ_NONE; | ||
985 | |||
986 | pchregs = &(codec->chregs); | ||
1038 | if (audio_int & ADDRESS_IRQ) { | 987 | if (audio_int & ADDRESS_IRQ) { |
1039 | // get interrupt status for all channels | 988 | /* get interrupt status for all channels */ |
1040 | pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint)); | 989 | pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint)); |
1041 | for (channel = 0; channel < ALI_CHANNELS; channel++) { | 990 | for (channel = 0; channel < ALI_CHANNELS; channel++) |
1042 | snd_ali_update_ptr(codec, channel); | 991 | snd_ali_update_ptr(codec, channel); |
1043 | } | ||
1044 | } | 992 | } |
1045 | outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), | 993 | outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), |
1046 | ALI_REG(codec,ALI_MISCINT)); | 994 | ALI_REG(codec, ALI_MISCINT)); |
1047 | } | ||
1048 | |||
1049 | |||
1050 | static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) | ||
1051 | { | ||
1052 | struct snd_ali *codec = dev_id; | ||
1053 | 995 | ||
1054 | if (codec == NULL) | ||
1055 | return IRQ_NONE; | ||
1056 | snd_ali_interrupt(codec); | ||
1057 | return IRQ_HANDLED; | 996 | return IRQ_HANDLED; |
1058 | } | 997 | } |
1059 | 998 | ||
1060 | 999 | ||
1061 | static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel) | 1000 | static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, |
1001 | int type, int rec, int channel) | ||
1062 | { | 1002 | { |
1063 | struct snd_ali_voice *pvoice = NULL; | 1003 | struct snd_ali_voice *pvoice; |
1064 | int idx; | 1004 | int idx; |
1065 | 1005 | ||
1066 | snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec); | 1006 | snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec); |
1067 | 1007 | ||
1068 | spin_lock_irq(&codec->voice_alloc); | 1008 | spin_lock_irq(&codec->voice_alloc); |
1069 | if (type == SNDRV_ALI_VOICE_TYPE_PCM) { | 1009 | if (type == SNDRV_ALI_VOICE_TYPE_PCM) { |
1070 | idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : | 1010 | idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : |
1071 | snd_ali_find_free_channel(codec,rec); | 1011 | snd_ali_find_free_channel(codec,rec); |
1072 | if(idx < 0) { | 1012 | if (idx < 0) { |
1073 | snd_printk(KERN_ERR "ali_alloc_voice: err.\n"); | 1013 | snd_printk(KERN_ERR "ali_alloc_voice: err.\n"); |
1074 | spin_unlock_irq(&codec->voice_alloc); | 1014 | spin_unlock_irq(&codec->voice_alloc); |
1075 | return NULL; | 1015 | return NULL; |
@@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ | |||
1087 | } | 1027 | } |
1088 | 1028 | ||
1089 | 1029 | ||
1090 | static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice) | 1030 | static void snd_ali_free_voice(struct snd_ali * codec, |
1031 | struct snd_ali_voice *pvoice) | ||
1091 | { | 1032 | { |
1092 | void (*private_free)(void *); | 1033 | void (*private_free)(void *); |
1093 | void *private_data; | 1034 | void *private_data; |
@@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo | |||
1101 | private_data = pvoice->private_data; | 1042 | private_data = pvoice->private_data; |
1102 | pvoice->private_free = NULL; | 1043 | pvoice->private_free = NULL; |
1103 | pvoice->private_data = NULL; | 1044 | pvoice->private_data = NULL; |
1104 | if (pvoice->pcm) { | 1045 | if (pvoice->pcm) |
1105 | snd_ali_free_channel_pcm(codec, pvoice->number); | 1046 | snd_ali_free_channel_pcm(codec, pvoice->number); |
1106 | } | ||
1107 | pvoice->use = pvoice->pcm = pvoice->synth = 0; | 1047 | pvoice->use = pvoice->pcm = pvoice->synth = 0; |
1108 | pvoice->substream = NULL; | 1048 | pvoice->substream = NULL; |
1109 | spin_unlock_irq(&codec->voice_alloc); | 1049 | spin_unlock_irq(&codec->voice_alloc); |
@@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo | |||
1112 | } | 1052 | } |
1113 | 1053 | ||
1114 | 1054 | ||
1115 | static void snd_ali_clear_voices(struct snd_ali * codec, | 1055 | static void snd_ali_clear_voices(struct snd_ali *codec, |
1116 | unsigned int v_min, | 1056 | unsigned int v_min, |
1117 | unsigned int v_max) | 1057 | unsigned int v_max) |
1118 | { | 1058 | { |
1119 | unsigned int i; | 1059 | unsigned int i; |
1120 | 1060 | ||
@@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec, | |||
1124 | } | 1064 | } |
1125 | } | 1065 | } |
1126 | 1066 | ||
1127 | static void snd_ali_write_voice_regs(struct snd_ali * codec, | 1067 | static void snd_ali_write_voice_regs(struct snd_ali *codec, |
1128 | unsigned int Channel, | 1068 | unsigned int Channel, |
1129 | unsigned int LBA, | 1069 | unsigned int LBA, |
1130 | unsigned int CSO, | 1070 | unsigned int CSO, |
@@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, | |||
1139 | { | 1079 | { |
1140 | unsigned int ctlcmds[4]; | 1080 | unsigned int ctlcmds[4]; |
1141 | 1081 | ||
1142 | outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR)); | 1082 | outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR)); |
1143 | 1083 | ||
1144 | ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff); | 1084 | ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff); |
1145 | ctlcmds[1] = LBA; | 1085 | ctlcmds[1] = LBA; |
@@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, | |||
1152 | 1092 | ||
1153 | outb(Channel, ALI_REG(codec, ALI_GC_CIR)); | 1093 | outb(Channel, ALI_REG(codec, ALI_GC_CIR)); |
1154 | 1094 | ||
1155 | outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS)); | 1095 | outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS)); |
1156 | outl(ctlcmds[1], ALI_REG(codec,ALI_LBA)); | 1096 | outl(ctlcmds[1], ALI_REG(codec, ALI_LBA)); |
1157 | outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA)); | 1097 | outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA)); |
1158 | outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC)); | 1098 | outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC)); |
1159 | 1099 | ||
1160 | outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */ | 1100 | outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */ |
1161 | outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */ | 1101 | outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */ |
@@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec) | |||
1165 | { | 1105 | { |
1166 | unsigned int delta; | 1106 | unsigned int delta; |
1167 | 1107 | ||
1168 | if (rate < 4000) rate = 4000; | 1108 | if (rate < 4000) |
1169 | if (rate > 48000) rate = 48000; | 1109 | rate = 4000; |
1110 | if (rate > 48000) | ||
1111 | rate = 48000; | ||
1170 | 1112 | ||
1171 | if (rec) { | 1113 | if (rec) { |
1172 | if (rate == 44100) | 1114 | if (rate == 44100) |
@@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) | |||
1201 | */ | 1143 | */ |
1202 | CTRL = 0x00000001; | 1144 | CTRL = 0x00000001; |
1203 | if (snd_pcm_format_width(runtime->format) == 16) | 1145 | if (snd_pcm_format_width(runtime->format) == 16) |
1204 | CTRL |= 0x00000008; // 16-bit data | 1146 | CTRL |= 0x00000008; /* 16-bit data */ |
1205 | if (!snd_pcm_format_unsigned(runtime->format)) | 1147 | if (!snd_pcm_format_unsigned(runtime->format)) |
1206 | CTRL |= 0x00000002; // signed data | 1148 | CTRL |= 0x00000002; /* signed data */ |
1207 | if (runtime->channels > 1) | 1149 | if (runtime->channels > 1) |
1208 | CTRL |= 0x00000004; // stereo data | 1150 | CTRL |= 0x00000004; /* stereo data */ |
1209 | return CTRL; | 1151 | return CTRL; |
1210 | } | 1152 | } |
1211 | 1153 | ||
@@ -1213,12 +1155,6 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) | |||
1213 | * PCM part | 1155 | * PCM part |
1214 | */ | 1156 | */ |
1215 | 1157 | ||
1216 | static int snd_ali_ioctl(struct snd_pcm_substream *substream, | ||
1217 | unsigned int cmd, void *arg) | ||
1218 | { | ||
1219 | return snd_pcm_lib_ioctl(substream, cmd, arg); | ||
1220 | } | ||
1221 | |||
1222 | static int snd_ali_trigger(struct snd_pcm_substream *substream, | 1158 | static int snd_ali_trigger(struct snd_pcm_substream *substream, |
1223 | int cmd) | 1159 | int cmd) |
1224 | 1160 | ||
@@ -1226,17 +1162,19 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, | |||
1226 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1162 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1227 | struct snd_pcm_substream *s; | 1163 | struct snd_pcm_substream *s; |
1228 | unsigned int what, whati, capture_flag; | 1164 | unsigned int what, whati, capture_flag; |
1229 | struct snd_ali_voice *pvoice = NULL, *evoice = NULL; | 1165 | struct snd_ali_voice *pvoice, *evoice; |
1230 | unsigned int val; | 1166 | unsigned int val; |
1231 | int do_start; | 1167 | int do_start; |
1232 | 1168 | ||
1233 | switch (cmd) { | 1169 | switch (cmd) { |
1234 | case SNDRV_PCM_TRIGGER_START: | 1170 | case SNDRV_PCM_TRIGGER_START: |
1235 | case SNDRV_PCM_TRIGGER_RESUME: | 1171 | case SNDRV_PCM_TRIGGER_RESUME: |
1236 | do_start = 1; break; | 1172 | do_start = 1; |
1173 | break; | ||
1237 | case SNDRV_PCM_TRIGGER_STOP: | 1174 | case SNDRV_PCM_TRIGGER_STOP: |
1238 | case SNDRV_PCM_TRIGGER_SUSPEND: | 1175 | case SNDRV_PCM_TRIGGER_SUSPEND: |
1239 | do_start = 0; break; | 1176 | do_start = 0; |
1177 | break; | ||
1240 | default: | 1178 | default: |
1241 | return -EINVAL; | 1179 | return -EINVAL; |
1242 | } | 1180 | } |
@@ -1247,9 +1185,9 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, | |||
1247 | pvoice = s->runtime->private_data; | 1185 | pvoice = s->runtime->private_data; |
1248 | evoice = pvoice->extra; | 1186 | evoice = pvoice->extra; |
1249 | what |= 1 << (pvoice->number & 0x1f); | 1187 | what |= 1 << (pvoice->number & 0x1f); |
1250 | if (evoice == NULL) { | 1188 | if (evoice == NULL) |
1251 | whati |= 1 << (pvoice->number & 0x1f); | 1189 | whati |= 1 << (pvoice->number & 0x1f); |
1252 | } else { | 1190 | else { |
1253 | whati |= 1 << (evoice->number & 0x1f); | 1191 | whati |= 1 << (evoice->number & 0x1f); |
1254 | what |= 1 << (evoice->number & 0x1f); | 1192 | what |= 1 << (evoice->number & 0x1f); |
1255 | } | 1193 | } |
@@ -1268,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, | |||
1268 | } | 1206 | } |
1269 | } | 1207 | } |
1270 | spin_lock(&codec->reg_lock); | 1208 | spin_lock(&codec->reg_lock); |
1271 | if (! do_start) { | 1209 | if (!do_start) |
1272 | outl(what, ALI_REG(codec, ALI_STOP)); | 1210 | outl(what, ALI_REG(codec, ALI_STOP)); |
1273 | } | ||
1274 | val = inl(ALI_REG(codec, ALI_AINTEN)); | 1211 | val = inl(ALI_REG(codec, ALI_AINTEN)); |
1275 | if (do_start) { | 1212 | if (do_start) |
1276 | val |= whati; | 1213 | val |= whati; |
1277 | } else { | 1214 | else |
1278 | val &= ~whati; | 1215 | val &= ~whati; |
1279 | } | ||
1280 | outl(val, ALI_REG(codec, ALI_AINTEN)); | 1216 | outl(val, ALI_REG(codec, ALI_AINTEN)); |
1281 | if (do_start) { | 1217 | if (do_start) |
1282 | outl(what, ALI_REG(codec, ALI_START)); | 1218 | outl(what, ALI_REG(codec, ALI_START)); |
1283 | } | 1219 | snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati); |
1284 | snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati); | ||
1285 | spin_unlock(&codec->reg_lock); | 1220 | spin_unlock(&codec->reg_lock); |
1286 | 1221 | ||
1287 | return 0; | 1222 | return 0; |
1288 | } | 1223 | } |
1289 | 1224 | ||
1290 | static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, | 1225 | static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, |
1291 | struct snd_pcm_hw_params *hw_params) | 1226 | struct snd_pcm_hw_params *hw_params) |
1292 | { | 1227 | { |
1293 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1228 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1294 | struct snd_pcm_runtime *runtime = substream->runtime; | 1229 | struct snd_pcm_runtime *runtime = substream->runtime; |
1295 | struct snd_ali_voice *pvoice = runtime->private_data; | 1230 | struct snd_ali_voice *pvoice = runtime->private_data; |
1296 | struct snd_ali_voice *evoice = pvoice->extra; | 1231 | struct snd_ali_voice *evoice = pvoice->extra; |
1297 | int err; | 1232 | int err; |
1298 | err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 1233 | |
1299 | if (err < 0) return err; | 1234 | err = snd_pcm_lib_malloc_pages(substream, |
1235 | params_buffer_bytes(hw_params)); | ||
1236 | if (err < 0) | ||
1237 | return err; | ||
1300 | 1238 | ||
1301 | /* voice management */ | 1239 | /* voice management */ |
1302 | 1240 | ||
1303 | if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) { | 1241 | if (params_buffer_size(hw_params) / 2 != |
1304 | if (evoice == NULL) { | 1242 | params_period_size(hw_params)) { |
1305 | evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1); | 1243 | if (!evoice) { |
1306 | if (evoice == NULL) | 1244 | evoice = snd_ali_alloc_voice(codec, |
1245 | SNDRV_ALI_VOICE_TYPE_PCM, | ||
1246 | 0, -1); | ||
1247 | if (!evoice) | ||
1307 | return -ENOMEM; | 1248 | return -ENOMEM; |
1308 | pvoice->extra = evoice; | 1249 | pvoice->extra = evoice; |
1309 | evoice->substream = substream; | 1250 | evoice->substream = substream; |
1310 | } | 1251 | } |
1311 | } else { | 1252 | } else { |
1312 | if (evoice != NULL) { | 1253 | if (!evoice) { |
1313 | snd_ali_free_voice(codec, evoice); | 1254 | snd_ali_free_voice(codec, evoice); |
1314 | pvoice->extra = evoice = NULL; | 1255 | pvoice->extra = evoice = NULL; |
1315 | } | 1256 | } |
@@ -1326,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) | |||
1326 | struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; | 1267 | struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; |
1327 | 1268 | ||
1328 | snd_pcm_lib_free_pages(substream); | 1269 | snd_pcm_lib_free_pages(substream); |
1329 | if (evoice != NULL) { | 1270 | if (!evoice) { |
1330 | snd_ali_free_voice(codec, evoice); | 1271 | snd_ali_free_voice(codec, evoice); |
1331 | pvoice->extra = NULL; | 1272 | pvoice->extra = NULL; |
1332 | } | 1273 | } |
@@ -1334,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) | |||
1334 | } | 1275 | } |
1335 | 1276 | ||
1336 | static int snd_ali_hw_params(struct snd_pcm_substream *substream, | 1277 | static int snd_ali_hw_params(struct snd_pcm_substream *substream, |
1337 | struct snd_pcm_hw_params *hw_params) | 1278 | struct snd_pcm_hw_params *hw_params) |
1338 | { | 1279 | { |
1339 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 1280 | return snd_pcm_lib_malloc_pages(substream, |
1281 | params_buffer_bytes(hw_params)); | ||
1340 | } | 1282 | } |
1341 | 1283 | ||
1342 | static int snd_ali_hw_free(struct snd_pcm_substream *substream) | 1284 | static int snd_ali_hw_free(struct snd_pcm_substream *substream) |
@@ -1367,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) | |||
1367 | /* set Delta (rate) value */ | 1309 | /* set Delta (rate) value */ |
1368 | Delta = snd_ali_convert_rate(runtime->rate, 0); | 1310 | Delta = snd_ali_convert_rate(runtime->rate, 0); |
1369 | 1311 | ||
1370 | if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || | 1312 | if (pvoice->number == ALI_SPDIF_IN_CHANNEL || |
1371 | (pvoice->number == ALI_PCM_IN_CHANNEL)) | 1313 | pvoice->number == ALI_PCM_IN_CHANNEL) |
1372 | snd_ali_disable_special_channel(codec, pvoice->number); | 1314 | snd_ali_disable_special_channel(codec, pvoice->number); |
1373 | else if (codec->spdif_support && | 1315 | else if (codec->spdif_support && |
1374 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE) | 1316 | (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & |
1375 | && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) { | 1317 | ALI_SPDIF_OUT_CH_ENABLE) |
1318 | && pvoice->number == ALI_SPDIF_OUT_CHANNEL) { | ||
1376 | snd_ali_set_spdif_out_rate(codec, runtime->rate); | 1319 | snd_ali_set_spdif_out_rate(codec, runtime->rate); |
1377 | Delta = 0x1000; | 1320 | Delta = 0x1000; |
1378 | } | 1321 | } |
@@ -1386,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) | |||
1386 | /* set target ESO for channel */ | 1329 | /* set target ESO for channel */ |
1387 | pvoice->eso = runtime->buffer_size; | 1330 | pvoice->eso = runtime->buffer_size; |
1388 | 1331 | ||
1389 | snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count); | 1332 | snd_ali_printk("playback_prepare: eso=%xh count=%xh\n", |
1333 | pvoice->eso, pvoice->count); | ||
1390 | 1334 | ||
1391 | /* set ESO to capture first MIDLP interrupt */ | 1335 | /* set ESO to capture first MIDLP interrupt */ |
1392 | ESO = pvoice->eso -1; | 1336 | ESO = pvoice->eso -1; |
@@ -1397,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) | |||
1397 | PAN = 0; | 1341 | PAN = 0; |
1398 | VOL = 0; | 1342 | VOL = 0; |
1399 | EC = 0; | 1343 | EC = 0; |
1400 | snd_ali_printk("playback_prepare:\n ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); | 1344 | snd_ali_printk("playback_prepare:\n"); |
1401 | snd_ali_write_voice_regs( codec, | 1345 | snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n", |
1402 | pvoice->number, | 1346 | pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); |
1403 | LBA, | 1347 | snd_ali_write_voice_regs(codec, |
1404 | 0, /* cso */ | 1348 | pvoice->number, |
1405 | ESO, | 1349 | LBA, |
1406 | Delta, | 1350 | 0, /* cso */ |
1407 | 0, /* alpha */ | 1351 | ESO, |
1408 | GVSEL, | 1352 | Delta, |
1409 | PAN, | 1353 | 0, /* alpha */ |
1410 | VOL, | 1354 | GVSEL, |
1411 | CTRL, | 1355 | PAN, |
1412 | EC); | 1356 | VOL, |
1413 | if (evoice != NULL) { | 1357 | CTRL, |
1358 | EC); | ||
1359 | if (!evoice) { | ||
1414 | evoice->count = pvoice->count; | 1360 | evoice->count = pvoice->count; |
1415 | evoice->eso = pvoice->count << 1; | 1361 | evoice->eso = pvoice->count << 1; |
1416 | ESO = evoice->eso - 1; | 1362 | ESO = evoice->eso - 1; |
1417 | snd_ali_write_voice_regs(codec, | 1363 | snd_ali_write_voice_regs(codec, |
1418 | evoice->number, | 1364 | evoice->number, |
1419 | LBA, | 1365 | LBA, |
1420 | 0, /* cso */ | 1366 | 0, /* cso */ |
1421 | ESO, | 1367 | ESO, |
1422 | Delta, | 1368 | Delta, |
1423 | 0, /* alpha */ | 1369 | 0, /* alpha */ |
1424 | GVSEL, | 1370 | GVSEL, |
1425 | (unsigned int)0x7f, | 1371 | 0x7f, |
1426 | (unsigned int)0x3ff, | 1372 | 0x3ff, |
1427 | CTRL, | 1373 | CTRL, |
1428 | EC); | 1374 | EC); |
1429 | } | 1375 | } |
1430 | spin_unlock_irq(&codec->reg_lock); | 1376 | spin_unlock_irq(&codec->reg_lock); |
1431 | return 0; | 1377 | return 0; |
@@ -1457,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1457 | pvoice->number == ALI_MODEM_OUT_CHANNEL) ? | 1403 | pvoice->number == ALI_MODEM_OUT_CHANNEL) ? |
1458 | 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode); | 1404 | 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode); |
1459 | 1405 | ||
1460 | // Prepare capture intr channel | 1406 | /* Prepare capture intr channel */ |
1461 | if (pvoice->number == ALI_SPDIF_IN_CHANNEL) { | 1407 | if (pvoice->number == ALI_SPDIF_IN_CHANNEL) { |
1462 | 1408 | ||
1463 | unsigned int rate; | 1409 | unsigned int rate; |
@@ -1468,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1468 | 1414 | ||
1469 | rate = snd_ali_get_spdif_in_rate(codec); | 1415 | rate = snd_ali_get_spdif_in_rate(codec); |
1470 | if (rate == 0) { | 1416 | if (rate == 0) { |
1471 | snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n"); | 1417 | snd_printk(KERN_WARNING "ali_capture_preapre: " |
1418 | "spdif rate detect err!\n"); | ||
1472 | rate = 48000; | 1419 | rate = 48000; |
1473 | } | 1420 | } |
1474 | spin_lock_irq(&codec->reg_lock); | 1421 | spin_lock_irq(&codec->reg_lock); |
@@ -1479,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1479 | } | 1426 | } |
1480 | 1427 | ||
1481 | if (rate != 48000) | 1428 | if (rate != 48000) |
1482 | Delta = ((rate << 12)/runtime->rate)&0x00ffff; | 1429 | Delta = ((rate << 12) / runtime->rate) & 0x00ffff; |
1483 | } | 1430 | } |
1484 | 1431 | ||
1485 | // set target ESO for channel | 1432 | /* set target ESO for channel */ |
1486 | pvoice->eso = runtime->buffer_size; | 1433 | pvoice->eso = runtime->buffer_size; |
1487 | 1434 | ||
1488 | // set interrupt count size | 1435 | /* set interrupt count size */ |
1489 | pvoice->count = runtime->period_size; | 1436 | pvoice->count = runtime->period_size; |
1490 | 1437 | ||
1491 | // set Loop Back Address | 1438 | /* set Loop Back Address */ |
1492 | LBA = runtime->dma_addr; | 1439 | LBA = runtime->dma_addr; |
1493 | 1440 | ||
1494 | // set ESO to capture first MIDLP interrupt | 1441 | /* set ESO to capture first MIDLP interrupt */ |
1495 | ESO = pvoice->eso - 1; | 1442 | ESO = pvoice->eso - 1; |
1496 | CTRL = snd_ali_control_mode(substream); | 1443 | CTRL = snd_ali_control_mode(substream); |
1497 | GVSEL = 0; | 1444 | GVSEL = 0; |
@@ -1512,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) | |||
1512 | CTRL, | 1459 | CTRL, |
1513 | EC); | 1460 | EC); |
1514 | 1461 | ||
1515 | |||
1516 | spin_unlock_irq(&codec->reg_lock); | 1462 | spin_unlock_irq(&codec->reg_lock); |
1517 | 1463 | ||
1518 | return 0; | 1464 | return 0; |
1519 | } | 1465 | } |
1520 | 1466 | ||
1521 | 1467 | ||
1522 | static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream) | 1468 | static snd_pcm_uframes_t |
1469 | snd_ali_playback_pointer(struct snd_pcm_substream *substream) | ||
1523 | { | 1470 | { |
1524 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1471 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1525 | struct snd_pcm_runtime *runtime = substream->runtime; | 1472 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -1561,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) | |||
1561 | 1508 | ||
1562 | static struct snd_pcm_hardware snd_ali_playback = | 1509 | static struct snd_pcm_hardware snd_ali_playback = |
1563 | { | 1510 | { |
1564 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1511 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1565 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1512 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1566 | SNDRV_PCM_INFO_MMAP_VALID | | 1513 | SNDRV_PCM_INFO_MMAP_VALID | |
1567 | SNDRV_PCM_INFO_RESUME | | 1514 | SNDRV_PCM_INFO_RESUME | |
1568 | SNDRV_PCM_INFO_SYNC_START), | 1515 | SNDRV_PCM_INFO_SYNC_START), |
1569 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1516 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | |
1570 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), | 1517 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), |
1571 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1518 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
1572 | .rate_min = 4000, | 1519 | .rate_min = 4000, |
1573 | .rate_max = 48000, | 1520 | .rate_max = 48000, |
1574 | .channels_min = 1, | 1521 | .channels_min = 1, |
@@ -1587,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback = | |||
1587 | 1534 | ||
1588 | static struct snd_pcm_hardware snd_ali_capture = | 1535 | static struct snd_pcm_hardware snd_ali_capture = |
1589 | { | 1536 | { |
1590 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1537 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1591 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1538 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1592 | SNDRV_PCM_INFO_MMAP_VALID | | 1539 | SNDRV_PCM_INFO_MMAP_VALID | |
1593 | SNDRV_PCM_INFO_RESUME | | 1540 | SNDRV_PCM_INFO_RESUME | |
1594 | SNDRV_PCM_INFO_SYNC_START), | 1541 | SNDRV_PCM_INFO_SYNC_START), |
1595 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1542 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | |
1596 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), | 1543 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), |
1597 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1544 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
1598 | .rate_min = 4000, | 1545 | .rate_min = 4000, |
1599 | .rate_max = 48000, | 1546 | .rate_max = 48000, |
1600 | .channels_min = 1, | 1547 | .channels_min = 1, |
@@ -1618,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime) | |||
1618 | } | 1565 | } |
1619 | } | 1566 | } |
1620 | 1567 | ||
1621 | static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel, | 1568 | static int snd_ali_open(struct snd_pcm_substream *substream, int rec, |
1622 | struct snd_pcm_hardware *phw) | 1569 | int channel, struct snd_pcm_hardware *phw) |
1623 | { | 1570 | { |
1624 | struct snd_ali *codec = snd_pcm_substream_chip(substream); | 1571 | struct snd_ali *codec = snd_pcm_substream_chip(substream); |
1625 | struct snd_pcm_runtime *runtime = substream->runtime; | 1572 | struct snd_pcm_runtime *runtime = substream->runtime; |
1626 | struct snd_ali_voice *pvoice; | 1573 | struct snd_ali_voice *pvoice; |
1627 | 1574 | ||
1628 | pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel); | 1575 | pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, |
1629 | if (pvoice == NULL) | 1576 | channel); |
1577 | if (!pvoice) | ||
1630 | return -EAGAIN; | 1578 | return -EAGAIN; |
1631 | 1579 | ||
1632 | pvoice->substream = substream; | 1580 | pvoice->substream = substream; |
@@ -1635,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe | |||
1635 | 1583 | ||
1636 | runtime->hw = *phw; | 1584 | runtime->hw = *phw; |
1637 | snd_pcm_set_sync(substream); | 1585 | snd_pcm_set_sync(substream); |
1638 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); | 1586 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, |
1587 | 0, 64*1024); | ||
1639 | return 0; | 1588 | return 0; |
1640 | } | 1589 | } |
1641 | 1590 | ||
@@ -1667,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream) | |||
1667 | static struct snd_pcm_ops snd_ali_playback_ops = { | 1616 | static struct snd_pcm_ops snd_ali_playback_ops = { |
1668 | .open = snd_ali_playback_open, | 1617 | .open = snd_ali_playback_open, |
1669 | .close = snd_ali_playback_close, | 1618 | .close = snd_ali_playback_close, |
1670 | .ioctl = snd_ali_ioctl, | 1619 | .ioctl = snd_pcm_lib_ioctl, |
1671 | .hw_params = snd_ali_playback_hw_params, | 1620 | .hw_params = snd_ali_playback_hw_params, |
1672 | .hw_free = snd_ali_playback_hw_free, | 1621 | .hw_free = snd_ali_playback_hw_free, |
1673 | .prepare = snd_ali_playback_prepare, | 1622 | .prepare = snd_ali_playback_prepare, |
@@ -1678,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = { | |||
1678 | static struct snd_pcm_ops snd_ali_capture_ops = { | 1627 | static struct snd_pcm_ops snd_ali_capture_ops = { |
1679 | .open = snd_ali_capture_open, | 1628 | .open = snd_ali_capture_open, |
1680 | .close = snd_ali_close, | 1629 | .close = snd_ali_close, |
1681 | .ioctl = snd_ali_ioctl, | 1630 | .ioctl = snd_pcm_lib_ioctl, |
1682 | .hw_params = snd_ali_hw_params, | 1631 | .hw_params = snd_ali_hw_params, |
1683 | .hw_free = snd_ali_hw_free, | 1632 | .hw_free = snd_ali_hw_free, |
1684 | .prepare = snd_ali_prepare, | 1633 | .prepare = snd_ali_prepare, |
@@ -1695,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream, | |||
1695 | { | 1644 | { |
1696 | struct snd_ali *chip = snd_pcm_substream_chip(substream); | 1645 | struct snd_ali *chip = snd_pcm_substream_chip(substream); |
1697 | unsigned int modem_num = chip->num_of_codecs - 1; | 1646 | unsigned int modem_num = chip->num_of_codecs - 1; |
1698 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params)); | 1647 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, |
1648 | params_rate(hw_params)); | ||
1699 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); | 1649 | snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); |
1700 | return snd_ali_hw_params(substream, hw_params); | 1650 | return snd_ali_hw_params(substream, hw_params); |
1701 | } | 1651 | } |
1702 | 1652 | ||
1703 | static struct snd_pcm_hardware snd_ali_modem = | 1653 | static struct snd_pcm_hardware snd_ali_modem = |
1704 | { | 1654 | { |
1705 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1655 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1706 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1656 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1707 | SNDRV_PCM_INFO_MMAP_VALID | | 1657 | SNDRV_PCM_INFO_MMAP_VALID | |
1708 | SNDRV_PCM_INFO_RESUME | | 1658 | SNDRV_PCM_INFO_RESUME | |
1709 | SNDRV_PCM_INFO_SYNC_START), | 1659 | SNDRV_PCM_INFO_SYNC_START), |
1710 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1660 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
1711 | .rates = SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000, | 1661 | .rates = (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 | |
1662 | SNDRV_PCM_RATE_16000), | ||
1712 | .rate_min = 8000, | 1663 | .rate_min = 8000, |
1713 | .rate_max = 16000, | 1664 | .rate_max = 16000, |
1714 | .channels_min = 1, | 1665 | .channels_min = 1, |
@@ -1721,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem = | |||
1721 | .fifo_size = 0, | 1672 | .fifo_size = 0, |
1722 | }; | 1673 | }; |
1723 | 1674 | ||
1724 | static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel) | 1675 | static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, |
1676 | int channel) | ||
1725 | { | 1677 | { |
1726 | static unsigned int rates [] = {8000,9600,12000,16000}; | 1678 | static unsigned int rates[] = {8000, 9600, 12000, 16000}; |
1727 | static struct snd_pcm_hw_constraint_list hw_constraint_rates = { | 1679 | static struct snd_pcm_hw_constraint_list hw_constraint_rates = { |
1728 | .count = ARRAY_SIZE(rates), | 1680 | .count = ARRAY_SIZE(rates), |
1729 | .list = rates, | 1681 | .list = rates, |
1730 | .mask = 0, | 1682 | .mask = 0, |
1731 | }; | 1683 | }; |
1732 | int err = snd_ali_open(substream, rec, channel, &snd_ali_modem); | 1684 | int err = snd_ali_open(substream, rec, channel, &snd_ali_modem); |
1685 | |||
1733 | if (err) | 1686 | if (err) |
1734 | return err; | 1687 | return err; |
1735 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | 1688 | return snd_pcm_hw_constraint_list(substream->runtime, 0, |
@@ -1786,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm) | |||
1786 | } | 1739 | } |
1787 | 1740 | ||
1788 | 1741 | ||
1789 | static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc) | 1742 | static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, |
1743 | struct ali_pcm_description *desc) | ||
1790 | { | 1744 | { |
1791 | struct snd_pcm *pcm; | 1745 | struct snd_pcm *pcm; |
1792 | int err; | 1746 | int err; |
@@ -1800,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ | |||
1800 | pcm->private_data = codec; | 1754 | pcm->private_data = codec; |
1801 | pcm->private_free = snd_ali_pcm_free; | 1755 | pcm->private_free = snd_ali_pcm_free; |
1802 | if (desc->playback_ops) | 1756 | if (desc->playback_ops) |
1803 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops); | 1757 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1758 | desc->playback_ops); | ||
1804 | if (desc->capture_ops) | 1759 | if (desc->capture_ops) |
1805 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops); | 1760 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
1761 | desc->capture_ops); | ||
1806 | 1762 | ||
1807 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 1763 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
1808 | snd_dma_pci_data(codec->pci), 64*1024, 128*1024); | 1764 | snd_dma_pci_data(codec->pci), |
1765 | 64*1024, 128*1024); | ||
1809 | 1766 | ||
1810 | pcm->info_flags = 0; | 1767 | pcm->info_flags = 0; |
1811 | pcm->dev_class = desc->class; | 1768 | pcm->dev_class = desc->class; |
@@ -1816,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ | |||
1816 | } | 1773 | } |
1817 | 1774 | ||
1818 | static struct ali_pcm_description ali_pcms[] = { | 1775 | static struct ali_pcm_description ali_pcms[] = { |
1819 | { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, | 1776 | { .name = "ALI 5451", |
1820 | { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM } | 1777 | .playback_num = ALI_CHANNELS, |
1778 | .capture_num = 1, | ||
1779 | .playback_ops = &snd_ali_playback_ops, | ||
1780 | .capture_ops = &snd_ali_capture_ops | ||
1781 | }, | ||
1782 | { .name = "ALI 5451 modem", | ||
1783 | .playback_num = 1, | ||
1784 | .capture_num = 1, | ||
1785 | .playback_ops = &snd_ali_modem_playback_ops, | ||
1786 | .capture_ops = &snd_ali_modem_capture_ops, | ||
1787 | .class = SNDRV_PCM_CLASS_MODEM | ||
1788 | } | ||
1821 | }; | 1789 | }; |
1822 | 1790 | ||
1823 | static int __devinit snd_ali_build_pcms(struct snd_ali *codec) | 1791 | static int __devinit snd_ali_build_pcms(struct snd_ali *codec) |
1824 | { | 1792 | { |
1825 | int i, err; | 1793 | int i, err; |
1826 | for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++) | 1794 | for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) { |
1827 | if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0) | 1795 | err = snd_ali_pcm(codec, i, &ali_pcms[i]); |
1796 | if (err < 0) | ||
1828 | return err; | 1797 | return err; |
1798 | } | ||
1829 | return 0; | 1799 | return 0; |
1830 | } | 1800 | } |
1831 | 1801 | ||
@@ -1835,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec) | |||
1835 | .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ | 1805 | .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ |
1836 | .put = snd_ali5451_spdif_put, .private_value = value} | 1806 | .put = snd_ali5451_spdif_put, .private_value = value} |
1837 | 1807 | ||
1838 | static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1808 | static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, |
1809 | struct snd_ctl_elem_info *uinfo) | ||
1839 | { | 1810 | { |
1840 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1811 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1841 | uinfo->count = 1; | 1812 | uinfo->count = 1; |
@@ -1844,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1844 | return 0; | 1815 | return 0; |
1845 | } | 1816 | } |
1846 | 1817 | ||
1847 | static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1818 | static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, |
1819 | struct snd_ctl_elem_value *ucontrol) | ||
1848 | { | 1820 | { |
1849 | struct snd_ali *codec = kcontrol->private_data; | 1821 | struct snd_ali *codec = kcontrol->private_data; |
1850 | unsigned int enable; | 1822 | unsigned int enable; |
@@ -1852,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1852 | enable = ucontrol->value.integer.value[0] ? 1 : 0; | 1824 | enable = ucontrol->value.integer.value[0] ? 1 : 0; |
1853 | 1825 | ||
1854 | spin_lock_irq(&codec->reg_lock); | 1826 | spin_lock_irq(&codec->reg_lock); |
1855 | switch(kcontrol->private_value) { | 1827 | switch (kcontrol->private_value) { |
1856 | case 0: | 1828 | case 0: |
1857 | enable = (codec->spdif_mask & 0x02) ? 1 : 0; | 1829 | enable = (codec->spdif_mask & 0x02) ? 1 : 0; |
1858 | break; | 1830 | break; |
1859 | case 1: | 1831 | case 1: |
1860 | enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0; | 1832 | enable = ((codec->spdif_mask & 0x02) && |
1833 | (codec->spdif_mask & 0x04)) ? 1 : 0; | ||
1861 | break; | 1834 | break; |
1862 | case 2: | 1835 | case 2: |
1863 | enable = (codec->spdif_mask & 0x01) ? 1 : 0; | 1836 | enable = (codec->spdif_mask & 0x01) ? 1 : 0; |
@@ -1870,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1870 | return 0; | 1843 | return 0; |
1871 | } | 1844 | } |
1872 | 1845 | ||
1873 | static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1846 | static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, |
1847 | struct snd_ctl_elem_value *ucontrol) | ||
1874 | { | 1848 | { |
1875 | struct snd_ali *codec = kcontrol->private_data; | 1849 | struct snd_ali *codec = kcontrol->private_data; |
1876 | unsigned int change = 0, enable = 0; | 1850 | unsigned int change = 0, enable = 0; |
@@ -1937,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = { | |||
1937 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) | 1911 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) |
1938 | }; | 1912 | }; |
1939 | 1913 | ||
1940 | static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus) | ||
1941 | { | ||
1942 | struct snd_ali *codec = bus->private_data; | ||
1943 | codec->ac97_bus = NULL; | ||
1944 | } | ||
1945 | |||
1946 | static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97) | ||
1947 | { | ||
1948 | struct snd_ali *codec = ac97->private_data; | ||
1949 | codec->ac97[ac97->num] = NULL; | ||
1950 | } | ||
1951 | |||
1952 | static int __devinit snd_ali_mixer(struct snd_ali * codec) | 1914 | static int __devinit snd_ali_mixer(struct snd_ali * codec) |
1953 | { | 1915 | { |
1954 | struct snd_ac97_template ac97; | 1916 | struct snd_ac97_template ac97; |
@@ -1959,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) | |||
1959 | .read = snd_ali_codec_read, | 1921 | .read = snd_ali_codec_read, |
1960 | }; | 1922 | }; |
1961 | 1923 | ||
1962 | if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0) | 1924 | err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus); |
1925 | if (err < 0) | ||
1963 | return err; | 1926 | return err; |
1964 | codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus; | ||
1965 | 1927 | ||
1966 | memset(&ac97, 0, sizeof(ac97)); | 1928 | memset(&ac97, 0, sizeof(ac97)); |
1967 | ac97.private_data = codec; | 1929 | ac97.private_data = codec; |
1968 | ac97.private_free = snd_ali_mixer_free_ac97; | ||
1969 | 1930 | ||
1970 | for ( i = 0 ; i < codec->num_of_codecs ; i++) { | 1931 | for (i = 0; i < codec->num_of_codecs; i++) { |
1971 | ac97.num = i; | 1932 | ac97.num = i; |
1972 | if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) { | 1933 | err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]); |
1973 | snd_printk(KERN_ERR "ali mixer %d creating error.\n", i); | 1934 | if (err < 0) { |
1974 | if(i == 0) | 1935 | snd_printk(KERN_ERR |
1936 | "ali mixer %d creating error.\n", i); | ||
1937 | if (i == 0) | ||
1975 | return err; | 1938 | return err; |
1976 | codec->num_of_codecs = 1; | 1939 | codec->num_of_codecs = 1; |
1977 | break; | 1940 | break; |
@@ -1979,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) | |||
1979 | } | 1942 | } |
1980 | 1943 | ||
1981 | if (codec->spdif_support) { | 1944 | if (codec->spdif_support) { |
1982 | for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { | 1945 | for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { |
1983 | err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); | 1946 | err = snd_ctl_add(codec->card, |
1984 | if (err < 0) return err; | 1947 | snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); |
1948 | if (err < 0) | ||
1949 | return err; | ||
1985 | } | 1950 | } |
1986 | } | 1951 | } |
1987 | return 0; | 1952 | return 0; |
@@ -1996,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) | |||
1996 | int i, j; | 1961 | int i, j; |
1997 | 1962 | ||
1998 | im = chip->image; | 1963 | im = chip->image; |
1999 | if (! im) | 1964 | if (!im) |
2000 | return 0; | 1965 | return 0; |
2001 | 1966 | ||
2002 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 1967 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
2003 | for(i = 0 ; i < chip->num_of_codecs ; i++) { | 1968 | for (i = 0; i < chip->num_of_codecs; i++) { |
2004 | snd_pcm_suspend_all(chip->pcm[i]); | 1969 | snd_pcm_suspend_all(chip->pcm[i]); |
2005 | snd_ac97_suspend(chip->ac97[i]); | 1970 | snd_ac97_suspend(chip->ac97[i]); |
2006 | } | 1971 | } |
@@ -2008,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) | |||
2008 | spin_lock_irq(&chip->reg_lock); | 1973 | spin_lock_irq(&chip->reg_lock); |
2009 | 1974 | ||
2010 | im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); | 1975 | im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); |
2011 | // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); | 1976 | /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */ |
2012 | im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP)); | 1977 | im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP)); |
2013 | 1978 | ||
2014 | // disable all IRQ bits | 1979 | /* disable all IRQ bits */ |
2015 | outl(0, ALI_REG(chip, ALI_MISCINT)); | 1980 | outl(0, ALI_REG(chip, ALI_MISCINT)); |
2016 | 1981 | ||
2017 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { | 1982 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { |
@@ -2026,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) | |||
2026 | im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0)); | 1991 | im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0)); |
2027 | } | 1992 | } |
2028 | 1993 | ||
2029 | // stop all HW channel | 1994 | /* stop all HW channel */ |
2030 | outl(0xffffffff, ALI_REG(chip, ALI_STOP)); | 1995 | outl(0xffffffff, ALI_REG(chip, ALI_STOP)); |
2031 | 1996 | ||
2032 | spin_unlock_irq(&chip->reg_lock); | 1997 | spin_unlock_irq(&chip->reg_lock); |
@@ -2045,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci) | |||
2045 | int i, j; | 2010 | int i, j; |
2046 | 2011 | ||
2047 | im = chip->image; | 2012 | im = chip->image; |
2048 | if (! im) | 2013 | if (!im) |
2049 | return 0; | 2014 | return 0; |
2050 | 2015 | ||
2051 | pci_set_power_state(pci, PCI_D0); | 2016 | pci_set_power_state(pci, PCI_D0); |
@@ -2067,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci) | |||
2067 | } | 2032 | } |
2068 | 2033 | ||
2069 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { | 2034 | for (i = 0; i < ALI_GLOBAL_REGS; i++) { |
2070 | if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START)) | 2035 | if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || |
2036 | (i*4 == ALI_START)) | ||
2071 | continue; | 2037 | continue; |
2072 | outl(im->regs[i], ALI_REG(chip, i*4)); | 2038 | outl(im->regs[i], ALI_REG(chip, i*4)); |
2073 | } | 2039 | } |
2074 | 2040 | ||
2075 | // start HW channel | 2041 | /* start HW channel */ |
2076 | outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); | 2042 | outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); |
2077 | // restore IRQ enable bits | 2043 | /* restore IRQ enable bits */ |
2078 | outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); | 2044 | outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); |
2079 | 2045 | ||
2080 | spin_unlock_irq(&chip->reg_lock); | 2046 | spin_unlock_irq(&chip->reg_lock); |
2081 | 2047 | ||
2082 | for(i = 0 ; i < chip->num_of_codecs ; i++) | 2048 | for (i = 0 ; i < chip->num_of_codecs; i++) |
2083 | snd_ac97_resume(chip->ac97[i]); | 2049 | snd_ac97_resume(chip->ac97[i]); |
2084 | 2050 | ||
2085 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 2051 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
@@ -2111,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2111 | { | 2077 | { |
2112 | unsigned int legacy; | 2078 | unsigned int legacy; |
2113 | unsigned char temp; | 2079 | unsigned char temp; |
2114 | struct pci_dev *pci_dev = NULL; | 2080 | struct pci_dev *pci_dev; |
2115 | 2081 | ||
2116 | snd_ali_printk("chip initializing ... \n"); | 2082 | snd_ali_printk("chip initializing ... \n"); |
2117 | 2083 | ||
@@ -2144,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2144 | outb(0x10, ALI_REG(codec, ALI_MPUR2)); | 2110 | outb(0x10, ALI_REG(codec, ALI_MPUR2)); |
2145 | 2111 | ||
2146 | codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID); | 2112 | codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID); |
2147 | codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS); | 2113 | codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, |
2114 | AC97_EXTENDED_STATUS); | ||
2148 | if (codec->spdif_support) { | 2115 | if (codec->spdif_support) { |
2149 | snd_ali_enable_spdif_out(codec); | 2116 | snd_ali_enable_spdif_out(codec); |
2150 | codec->spdif_mask = 0x00000002; | 2117 | codec->spdif_mask = 0x00000002; |
@@ -2156,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2156 | if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) { | 2123 | if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) { |
2157 | codec->num_of_codecs++; | 2124 | codec->num_of_codecs++; |
2158 | outl(inl(ALI_REG(codec, ALI_SCTRL)) | | 2125 | outl(inl(ALI_REG(codec, ALI_SCTRL)) | |
2159 | (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN), | 2126 | (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 | |
2160 | ALI_REG(codec, ALI_SCTRL)); | 2127 | ALI_SCTRL_LINE_OUT_EN), |
2128 | ALI_REG(codec, ALI_SCTRL)); | ||
2161 | } | 2129 | } |
2162 | 2130 | ||
2163 | snd_ali_printk("chip initialize succeed.\n"); | 2131 | snd_ali_printk("chip initialize succeed.\n"); |
@@ -2166,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec) | |||
2166 | } | 2134 | } |
2167 | 2135 | ||
2168 | /* proc for register dump */ | 2136 | /* proc for register dump */ |
2169 | static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) | 2137 | static void snd_ali_proc_read(struct snd_info_entry *entry, |
2138 | struct snd_info_buffer *buf) | ||
2170 | { | 2139 | { |
2171 | struct snd_ali *codec = entry->private_data; | 2140 | struct snd_ali *codec = entry->private_data; |
2172 | int i; | 2141 | int i; |
2173 | for(i = 0 ; i < 256 ; i+= 4) | 2142 | for (i = 0; i < 256 ; i+= 4) |
2174 | snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i))); | 2143 | snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i))); |
2175 | } | 2144 | } |
2176 | 2145 | ||
2177 | static void __devinit snd_ali_proc_init(struct snd_ali *codec) | 2146 | static void __devinit snd_ali_proc_init(struct snd_ali *codec) |
2178 | { | 2147 | { |
2179 | struct snd_info_entry *entry; | 2148 | struct snd_info_entry *entry; |
2180 | if(!snd_card_proc_new(codec->card, "ali5451", &entry)) | 2149 | if (!snd_card_proc_new(codec->card, "ali5451", &entry)) |
2181 | snd_info_set_text_ops(entry, codec, snd_ali_proc_read); | 2150 | snd_info_set_text_ops(entry, codec, snd_ali_proc_read); |
2182 | } | 2151 | } |
2183 | 2152 | ||
@@ -2186,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) | |||
2186 | int err; | 2155 | int err; |
2187 | 2156 | ||
2188 | snd_ali_printk("resouces allocation ...\n"); | 2157 | snd_ali_printk("resouces allocation ...\n"); |
2189 | if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0) | 2158 | err = pci_request_regions(codec->pci, "ALI 5451"); |
2159 | if (err < 0) | ||
2190 | return err; | 2160 | return err; |
2191 | codec->port = pci_resource_start(codec->pci, 0); | 2161 | codec->port = pci_resource_start(codec->pci, 0); |
2192 | 2162 | ||
@@ -2199,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) | |||
2199 | snd_ali_printk("resouces allocated.\n"); | 2169 | snd_ali_printk("resouces allocated.\n"); |
2200 | return 0; | 2170 | return 0; |
2201 | } | 2171 | } |
2202 | static int snd_ali_dev_free(struct snd_device *device) | 2172 | static int snd_ali_dev_free(struct snd_device *device) |
2203 | { | 2173 | { |
2204 | struct snd_ali *codec=device->device_data; | 2174 | struct snd_ali *codec = device->device_data; |
2205 | snd_ali_free(codec); | 2175 | snd_ali_free(codec); |
2206 | return 0; | 2176 | return 0; |
2207 | } | 2177 | } |
@@ -2224,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card, | |||
2224 | snd_ali_printk("creating ...\n"); | 2194 | snd_ali_printk("creating ...\n"); |
2225 | 2195 | ||
2226 | /* enable PCI device */ | 2196 | /* enable PCI device */ |
2227 | if ((err = pci_enable_device(pci)) < 0) | 2197 | err = pci_enable_device(pci); |
2198 | if (err < 0) | ||
2228 | return err; | 2199 | return err; |
2229 | /* check, if we can restrict PCI DMA transfers to 31 bits */ | 2200 | /* check, if we can restrict PCI DMA transfers to 31 bits */ |
2230 | if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || | 2201 | if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || |
2231 | pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { | 2202 | pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { |
2232 | snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n"); | 2203 | snd_printk(KERN_ERR "architecture does not support " |
2204 | "31bit PCI busmaster DMA\n"); | ||
2233 | pci_disable_device(pci); | 2205 | pci_disable_device(pci); |
2234 | return -ENXIO; | 2206 | return -ENXIO; |
2235 | } | 2207 | } |
2236 | 2208 | ||
2237 | if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) { | 2209 | codec = kzalloc(sizeof(*codec), GFP_KERNEL); |
2210 | if (!codec) { | ||
2238 | pci_disable_device(pci); | 2211 | pci_disable_device(pci); |
2239 | return -ENOMEM; | 2212 | return -ENOMEM; |
2240 | } | 2213 | } |
@@ -2291,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card, | |||
2291 | 2264 | ||
2292 | /* M1533: southbridge */ | 2265 | /* M1533: southbridge */ |
2293 | codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); | 2266 | codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); |
2294 | if (! codec->pci_m1533) { | 2267 | if (!codec->pci_m1533) { |
2295 | snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); | 2268 | snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); |
2296 | snd_ali_free(codec); | 2269 | snd_ali_free(codec); |
2297 | return -ENODEV; | 2270 | return -ENODEV; |
2298 | } | 2271 | } |
2299 | /* M7101: power management */ | 2272 | /* M7101: power management */ |
2300 | codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); | 2273 | codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); |
2301 | if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) { | 2274 | if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) { |
2302 | snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); | 2275 | snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); |
2303 | snd_ali_free(codec); | 2276 | snd_ali_free(codec); |
2304 | return -ENODEV; | 2277 | return -ENODEV; |
2305 | } | 2278 | } |
2306 | 2279 | ||
2307 | snd_ali_printk("snd_device_new is called.\n"); | 2280 | snd_ali_printk("snd_device_new is called.\n"); |
2308 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) { | 2281 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops); |
2282 | if (err < 0) { | ||
2309 | snd_ali_free(codec); | 2283 | snd_ali_free(codec); |
2310 | return err; | 2284 | return err; |
2311 | } | 2285 | } |
@@ -2313,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card, | |||
2313 | snd_card_set_dev(card, &pci->dev); | 2287 | snd_card_set_dev(card, &pci->dev); |
2314 | 2288 | ||
2315 | /* initialise synth voices*/ | 2289 | /* initialise synth voices*/ |
2316 | for (i = 0; i < ALI_CHANNELS; i++ ) { | 2290 | for (i = 0; i < ALI_CHANNELS; i++) |
2317 | codec->synth.voices[i].number = i; | 2291 | codec->synth.voices[i].number = i; |
2318 | } | ||
2319 | 2292 | ||
2320 | if ((err = snd_ali_chip_init(codec)) < 0) { | 2293 | err = snd_ali_chip_init(codec); |
2294 | if (err < 0) { | ||
2321 | snd_printk(KERN_ERR "ali create: chip init error.\n"); | 2295 | snd_printk(KERN_ERR "ali create: chip init error.\n"); |
2322 | return err; | 2296 | return err; |
2323 | } | 2297 | } |
2324 | 2298 | ||
2325 | #ifdef CONFIG_PM | 2299 | #ifdef CONFIG_PM |
2326 | codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); | 2300 | codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); |
2327 | if (! codec->image) | 2301 | if (!codec->image) |
2328 | snd_printk(KERN_WARNING "can't allocate apm buffer\n"); | 2302 | snd_printk(KERN_WARNING "can't allocate apm buffer\n"); |
2329 | #endif | 2303 | #endif |
2330 | 2304 | ||
@@ -2346,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, | |||
2346 | snd_ali_printk("probe ...\n"); | 2320 | snd_ali_printk("probe ...\n"); |
2347 | 2321 | ||
2348 | card = snd_card_new(index, id, THIS_MODULE, 0); | 2322 | card = snd_card_new(index, id, THIS_MODULE, 0); |
2349 | if (card == NULL) | 2323 | if (!card) |
2350 | return -ENOMEM; | 2324 | return -ENOMEM; |
2351 | 2325 | ||
2352 | if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) { | 2326 | err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); |
2353 | snd_card_free(card); | 2327 | if (err < 0) |
2354 | return err; | 2328 | goto error; |
2355 | } | ||
2356 | card->private_data = codec; | 2329 | card->private_data = codec; |
2357 | 2330 | ||
2358 | snd_ali_printk("mixer building ...\n"); | 2331 | snd_ali_printk("mixer building ...\n"); |
2359 | if ((err = snd_ali_mixer(codec)) < 0) { | 2332 | err = snd_ali_mixer(codec); |
2360 | snd_card_free(card); | 2333 | if (err < 0) |
2361 | return err; | 2334 | goto error; |
2362 | } | ||
2363 | 2335 | ||
2364 | snd_ali_printk("pcm building ...\n"); | 2336 | snd_ali_printk("pcm building ...\n"); |
2365 | if ((err = snd_ali_build_pcms(codec)) < 0) { | 2337 | err = snd_ali_build_pcms(codec); |
2366 | snd_card_free(card); | 2338 | if (err < 0) |
2367 | return err; | 2339 | goto error; |
2368 | } | ||
2369 | 2340 | ||
2370 | snd_ali_proc_init(codec); | 2341 | snd_ali_proc_init(codec); |
2371 | 2342 | ||
@@ -2376,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, | |||
2376 | card->shortname, codec->port, codec->irq); | 2347 | card->shortname, codec->port, codec->irq); |
2377 | 2348 | ||
2378 | snd_ali_printk("register card.\n"); | 2349 | snd_ali_printk("register card.\n"); |
2379 | if ((err = snd_card_register(card)) < 0) { | 2350 | err = snd_card_register(card); |
2380 | snd_card_free(card); | 2351 | if (err < 0) |
2381 | return err; | 2352 | goto error; |
2382 | } | 2353 | |
2383 | pci_set_drvdata(pci, card); | 2354 | pci_set_drvdata(pci, card); |
2384 | return 0; | 2355 | return 0; |
2356 | |||
2357 | error: | ||
2358 | snd_card_free(card); | ||
2359 | return err; | ||
2385 | } | 2360 | } |
2386 | 2361 | ||
2387 | static void __devexit snd_ali_remove(struct pci_dev *pci) | 2362 | static void __devexit snd_ali_remove(struct pci_dev *pci) |