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 | |
| 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>
| -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) |
