diff options
| author | Takashi Iwai <tiwai@suse.de> | 2009-06-12 14:03:16 -0400 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2009-06-12 14:03:16 -0400 |
| commit | e3f86d3d3ce350144562d9bd035dc8a274fce58e (patch) | |
| tree | 6d31842f5d8598ea377c09556e455402a06a64fe | |
| parent | 056c1ebf1121ca6c16652d0c3fa306622ee338ac (diff) | |
| parent | 2233123f2776f29d3ac31df1fd1dc40c44d337a5 (diff) | |
Merge branch 'topic/ps3' into for-linus
* topic/ps3:
ALSA: sound/ps3: Correct existing and add missing annotations
ALSA: sound/ps3: Restructure driver source
ALSA: sound/ps3: Fix checkpatch issues
| -rw-r--r-- | sound/ppc/snd_ps3.c | 655 |
1 files changed, 304 insertions, 351 deletions
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index f361c26506aa..53c81a547613 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
| @@ -18,81 +18,31 @@ | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/dma-mapping.h> | ||
| 22 | #include <linux/dmapool.h> | ||
| 21 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
| 25 | #include <linux/io.h> | ||
| 26 | #include <linux/slab.h> | ||
| 27 | |||
| 28 | #include <sound/asound.h> | ||
| 29 | #include <sound/control.h> | ||
| 25 | #include <sound/core.h> | 30 | #include <sound/core.h> |
| 26 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
| 27 | #include <sound/pcm.h> | ||
| 28 | #include <sound/asound.h> | ||
| 29 | #include <sound/memalloc.h> | 32 | #include <sound/memalloc.h> |
| 33 | #include <sound/pcm.h> | ||
| 30 | #include <sound/pcm_params.h> | 34 | #include <sound/pcm_params.h> |
| 31 | #include <sound/control.h> | 35 | |
| 32 | #include <linux/dmapool.h> | ||
| 33 | #include <linux/dma-mapping.h> | ||
| 34 | #include <asm/firmware.h> | ||
| 35 | #include <asm/dma.h> | 36 | #include <asm/dma.h> |
| 37 | #include <asm/firmware.h> | ||
| 36 | #include <asm/lv1call.h> | 38 | #include <asm/lv1call.h> |
| 37 | #include <asm/ps3.h> | 39 | #include <asm/ps3.h> |
| 38 | #include <asm/ps3av.h> | 40 | #include <asm/ps3av.h> |
| 39 | 41 | ||
| 40 | #include "snd_ps3_reg.h" | ||
| 41 | #include "snd_ps3.h" | 42 | #include "snd_ps3.h" |
| 42 | 43 | #include "snd_ps3_reg.h" | |
| 43 | MODULE_LICENSE("GPL v2"); | ||
| 44 | MODULE_DESCRIPTION("PS3 sound driver"); | ||
| 45 | MODULE_AUTHOR("Sony Computer Entertainment Inc."); | ||
| 46 | |||
| 47 | /* module entries */ | ||
| 48 | static int __init snd_ps3_init(void); | ||
| 49 | static void __exit snd_ps3_exit(void); | ||
| 50 | |||
| 51 | /* ALSA snd driver ops */ | ||
| 52 | static int snd_ps3_pcm_open(struct snd_pcm_substream *substream); | ||
| 53 | static int snd_ps3_pcm_close(struct snd_pcm_substream *substream); | ||
| 54 | static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream); | ||
| 55 | static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, | ||
| 56 | int cmd); | ||
| 57 | static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream | ||
| 58 | *substream); | ||
| 59 | static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, | ||
| 60 | struct snd_pcm_hw_params *hw_params); | ||
| 61 | static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream); | ||
| 62 | |||
| 63 | |||
| 64 | /* ps3_system_bus_driver entries */ | ||
| 65 | static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev); | ||
| 66 | static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev); | ||
| 67 | |||
| 68 | /* address setup */ | ||
| 69 | static int snd_ps3_map_mmio(void); | ||
| 70 | static void snd_ps3_unmap_mmio(void); | ||
| 71 | static int snd_ps3_allocate_irq(void); | ||
| 72 | static void snd_ps3_free_irq(void); | ||
| 73 | static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start); | ||
| 74 | |||
| 75 | /* interrupt handler */ | ||
| 76 | static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id); | ||
| 77 | |||
| 78 | |||
| 79 | /* set sampling rate/format */ | ||
| 80 | static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream); | ||
| 81 | /* take effect parameter change */ | ||
| 82 | static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card); | ||
| 83 | /* initialize avsetting and take it effect */ | ||
| 84 | static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card); | ||
| 85 | /* setup dma */ | ||
| 86 | static int snd_ps3_program_dma(struct snd_ps3_card_info *card, | ||
| 87 | enum snd_ps3_dma_filltype filltype); | ||
| 88 | static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card); | ||
| 89 | |||
| 90 | static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void *vaddr, int ch); | ||
| 91 | 44 | ||
| 92 | 45 | ||
| 93 | module_init(snd_ps3_init); | ||
| 94 | module_exit(snd_ps3_exit); | ||
| 95 | |||
| 96 | /* | 46 | /* |
| 97 | * global | 47 | * global |
| 98 | */ | 48 | */ |
| @@ -165,25 +115,13 @@ static const struct snd_pcm_hardware snd_ps3_pcm_hw = { | |||
| 165 | .fifo_size = PS3_AUDIO_FIFO_SIZE | 115 | .fifo_size = PS3_AUDIO_FIFO_SIZE |
| 166 | }; | 116 | }; |
| 167 | 117 | ||
| 168 | static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = | ||
| 169 | { | ||
| 170 | .open = snd_ps3_pcm_open, | ||
| 171 | .close = snd_ps3_pcm_close, | ||
| 172 | .prepare = snd_ps3_pcm_prepare, | ||
| 173 | .ioctl = snd_pcm_lib_ioctl, | ||
| 174 | .trigger = snd_ps3_pcm_trigger, | ||
| 175 | .pointer = snd_ps3_pcm_pointer, | ||
| 176 | .hw_params = snd_ps3_pcm_hw_params, | ||
| 177 | .hw_free = snd_ps3_pcm_hw_free | ||
| 178 | }; | ||
| 179 | |||
| 180 | static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card, | 118 | static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card, |
| 181 | int count, int force_stop) | 119 | int count, int force_stop) |
| 182 | { | 120 | { |
| 183 | int dma_ch, done, retries, stop_forced = 0; | 121 | int dma_ch, done, retries, stop_forced = 0; |
| 184 | uint32_t status; | 122 | uint32_t status; |
| 185 | 123 | ||
| 186 | for (dma_ch = 0; dma_ch < 8; dma_ch ++) { | 124 | for (dma_ch = 0; dma_ch < 8; dma_ch++) { |
| 187 | retries = count; | 125 | retries = count; |
| 188 | do { | 126 | do { |
| 189 | status = read_reg(PS3_AUDIO_KICK(dma_ch)) & | 127 | status = read_reg(PS3_AUDIO_KICK(dma_ch)) & |
| @@ -259,9 +197,7 @@ static void snd_ps3_kick_dma(struct snd_ps3_card_info *card) | |||
| 259 | /* | 197 | /* |
| 260 | * convert virtual addr to ioif bus addr. | 198 | * convert virtual addr to ioif bus addr. |
| 261 | */ | 199 | */ |
| 262 | static dma_addr_t v_to_bus(struct snd_ps3_card_info *card, | 200 | static dma_addr_t v_to_bus(struct snd_ps3_card_info *card, void *paddr, int ch) |
| 263 | void * paddr, | ||
| 264 | int ch) | ||
| 265 | { | 201 | { |
| 266 | return card->dma_start_bus_addr[ch] + | 202 | return card->dma_start_bus_addr[ch] + |
| 267 | (paddr - card->dma_start_vaddr[ch]); | 203 | (paddr - card->dma_start_vaddr[ch]); |
| @@ -321,7 +257,7 @@ static int snd_ps3_program_dma(struct snd_ps3_card_info *card, | |||
| 321 | spin_lock_irqsave(&card->dma_lock, irqsave); | 257 | spin_lock_irqsave(&card->dma_lock, irqsave); |
| 322 | for (ch = 0; ch < 2; ch++) { | 258 | for (ch = 0; ch < 2; ch++) { |
| 323 | start_vaddr = card->dma_next_transfer_vaddr[0]; | 259 | start_vaddr = card->dma_next_transfer_vaddr[0]; |
| 324 | for (stage = 0; stage < fill_stages; stage ++) { | 260 | for (stage = 0; stage < fill_stages; stage++) { |
| 325 | dma_ch = stage * 2 + ch; | 261 | dma_ch = stage * 2 + ch; |
| 326 | if (silent) | 262 | if (silent) |
| 327 | dma_addr = card->null_buffer_start_dma_addr; | 263 | dma_addr = card->null_buffer_start_dma_addr; |
| @@ -372,6 +308,71 @@ static int snd_ps3_program_dma(struct snd_ps3_card_info *card, | |||
| 372 | } | 308 | } |
| 373 | 309 | ||
| 374 | /* | 310 | /* |
| 311 | * Interrupt handler | ||
| 312 | */ | ||
| 313 | static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id) | ||
| 314 | { | ||
| 315 | |||
| 316 | uint32_t port_intr; | ||
| 317 | int underflow_occured = 0; | ||
| 318 | struct snd_ps3_card_info *card = dev_id; | ||
| 319 | |||
| 320 | if (!card->running) { | ||
| 321 | update_reg(PS3_AUDIO_AX_IS, 0); | ||
| 322 | update_reg(PS3_AUDIO_INTR_0, 0); | ||
| 323 | return IRQ_HANDLED; | ||
| 324 | } | ||
| 325 | |||
| 326 | port_intr = read_reg(PS3_AUDIO_AX_IS); | ||
| 327 | /* | ||
| 328 | *serial buffer empty detected (every 4 times), | ||
| 329 | *program next dma and kick it | ||
| 330 | */ | ||
| 331 | if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) { | ||
| 332 | write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0)); | ||
| 333 | if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { | ||
| 334 | write_reg(PS3_AUDIO_AX_IS, port_intr); | ||
| 335 | underflow_occured = 1; | ||
| 336 | } | ||
| 337 | if (card->silent) { | ||
| 338 | /* we are still in silent time */ | ||
| 339 | snd_ps3_program_dma(card, | ||
| 340 | (underflow_occured) ? | ||
| 341 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL : | ||
| 342 | SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); | ||
| 343 | snd_ps3_kick_dma(card); | ||
| 344 | card->silent--; | ||
| 345 | } else { | ||
| 346 | snd_ps3_program_dma(card, | ||
| 347 | (underflow_occured) ? | ||
| 348 | SND_PS3_DMA_FILLTYPE_FIRSTFILL : | ||
| 349 | SND_PS3_DMA_FILLTYPE_RUNNING); | ||
| 350 | snd_ps3_kick_dma(card); | ||
| 351 | snd_pcm_period_elapsed(card->substream); | ||
| 352 | } | ||
| 353 | } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { | ||
| 354 | write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0)); | ||
| 355 | /* | ||
| 356 | * serial out underflow, but buffer empty not detected. | ||
| 357 | * in this case, fill fifo with 0 to recover. After | ||
| 358 | * filling dummy data, serial automatically start to | ||
| 359 | * consume them and then will generate normal buffer | ||
| 360 | * empty interrupts. | ||
| 361 | * If both buffer underflow and buffer empty are occured, | ||
| 362 | * it is better to do nomal data transfer than empty one | ||
| 363 | */ | ||
| 364 | snd_ps3_program_dma(card, | ||
| 365 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
| 366 | snd_ps3_kick_dma(card); | ||
| 367 | snd_ps3_program_dma(card, | ||
| 368 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
| 369 | snd_ps3_kick_dma(card); | ||
| 370 | } | ||
| 371 | /* clear interrupt cause */ | ||
| 372 | return IRQ_HANDLED; | ||
| 373 | }; | ||
| 374 | |||
| 375 | /* | ||
| 375 | * audio mute on/off | 376 | * audio mute on/off |
| 376 | * mute_on : 0 output enabled | 377 | * mute_on : 0 output enabled |
| 377 | * 1 mute | 378 | * 1 mute |
| @@ -382,6 +383,142 @@ static int snd_ps3_mute(int mute_on) | |||
| 382 | } | 383 | } |
| 383 | 384 | ||
| 384 | /* | 385 | /* |
| 386 | * av setting | ||
| 387 | * NOTE: calling this function may generate audio interrupt. | ||
| 388 | */ | ||
| 389 | static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card) | ||
| 390 | { | ||
| 391 | int ret, retries, i; | ||
| 392 | pr_debug("%s: start\n", __func__); | ||
| 393 | |||
| 394 | ret = ps3av_set_audio_mode(card->avs.avs_audio_ch, | ||
| 395 | card->avs.avs_audio_rate, | ||
| 396 | card->avs.avs_audio_width, | ||
| 397 | card->avs.avs_audio_format, | ||
| 398 | card->avs.avs_audio_source); | ||
| 399 | /* | ||
| 400 | * Reset the following unwanted settings: | ||
| 401 | */ | ||
| 402 | |||
| 403 | /* disable all 3wire buffers */ | ||
| 404 | update_mask_reg(PS3_AUDIO_AO_3WMCTRL, | ||
| 405 | ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) | | ||
| 406 | PS3_AUDIO_AO_3WMCTRL_ASOEN(1) | | ||
| 407 | PS3_AUDIO_AO_3WMCTRL_ASOEN(2) | | ||
| 408 | PS3_AUDIO_AO_3WMCTRL_ASOEN(3)), | ||
| 409 | 0); | ||
| 410 | wmb(); /* ensure the hardware sees the change */ | ||
| 411 | /* wait for actually stopped */ | ||
| 412 | retries = 1000; | ||
| 413 | while ((read_reg(PS3_AUDIO_AO_3WMCTRL) & | ||
| 414 | (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | | ||
| 415 | PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | | ||
| 416 | PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | | ||
| 417 | PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) && | ||
| 418 | --retries) { | ||
| 419 | udelay(1); | ||
| 420 | } | ||
| 421 | |||
| 422 | /* reset buffer pointer */ | ||
| 423 | for (i = 0; i < 4; i++) { | ||
| 424 | update_reg(PS3_AUDIO_AO_3WCTRL(i), | ||
| 425 | PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET); | ||
| 426 | udelay(10); | ||
| 427 | } | ||
| 428 | wmb(); /* ensure the hardware actually start resetting */ | ||
| 429 | |||
| 430 | /* enable 3wire#0 buffer */ | ||
| 431 | update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0)); | ||
| 432 | |||
| 433 | |||
| 434 | /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */ | ||
| 435 | update_mask_reg(PS3_AUDIO_AO_3WCTRL(0), | ||
| 436 | ~PS3_AUDIO_AO_3WCTRL_ASODF, | ||
| 437 | PS3_AUDIO_AO_3WCTRL_ASODF_LSB); | ||
| 438 | update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0), | ||
| 439 | ~PS3_AUDIO_AO_SPDCTRL_SPODF, | ||
| 440 | PS3_AUDIO_AO_SPDCTRL_SPODF_LSB); | ||
| 441 | /* ensure all the setting above is written back to register */ | ||
| 442 | wmb(); | ||
| 443 | /* avsetting driver altered AX_IE, caller must reset it if you want */ | ||
| 444 | pr_debug("%s: end\n", __func__); | ||
| 445 | return ret; | ||
| 446 | } | ||
| 447 | |||
| 448 | /* | ||
| 449 | * set sampling rate according to the substream | ||
| 450 | */ | ||
| 451 | static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) | ||
| 452 | { | ||
| 453 | struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); | ||
| 454 | struct snd_ps3_avsetting_info avs; | ||
| 455 | int ret; | ||
| 456 | |||
| 457 | avs = card->avs; | ||
| 458 | |||
| 459 | pr_debug("%s: called freq=%d width=%d\n", __func__, | ||
| 460 | substream->runtime->rate, | ||
| 461 | snd_pcm_format_width(substream->runtime->format)); | ||
| 462 | |||
| 463 | pr_debug("%s: before freq=%d width=%d\n", __func__, | ||
| 464 | card->avs.avs_audio_rate, card->avs.avs_audio_width); | ||
| 465 | |||
| 466 | /* sample rate */ | ||
| 467 | switch (substream->runtime->rate) { | ||
| 468 | case 44100: | ||
| 469 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K; | ||
| 470 | break; | ||
| 471 | case 48000: | ||
| 472 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; | ||
| 473 | break; | ||
| 474 | case 88200: | ||
| 475 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K; | ||
| 476 | break; | ||
| 477 | case 96000: | ||
| 478 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K; | ||
| 479 | break; | ||
| 480 | default: | ||
| 481 | pr_info("%s: invalid rate %d\n", __func__, | ||
| 482 | substream->runtime->rate); | ||
| 483 | return 1; | ||
| 484 | } | ||
| 485 | |||
| 486 | /* width */ | ||
| 487 | switch (snd_pcm_format_width(substream->runtime->format)) { | ||
| 488 | case 16: | ||
| 489 | avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; | ||
| 490 | break; | ||
| 491 | case 24: | ||
| 492 | avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24; | ||
| 493 | break; | ||
| 494 | default: | ||
| 495 | pr_info("%s: invalid width %d\n", __func__, | ||
| 496 | snd_pcm_format_width(substream->runtime->format)); | ||
| 497 | return 1; | ||
| 498 | } | ||
| 499 | |||
| 500 | memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8); | ||
| 501 | |||
| 502 | if (memcmp(&card->avs, &avs, sizeof(avs))) { | ||
| 503 | pr_debug("%s: after freq=%d width=%d\n", __func__, | ||
| 504 | card->avs.avs_audio_rate, card->avs.avs_audio_width); | ||
| 505 | |||
| 506 | card->avs = avs; | ||
| 507 | snd_ps3_change_avsetting(card); | ||
| 508 | ret = 0; | ||
| 509 | } else | ||
| 510 | ret = 1; | ||
| 511 | |||
| 512 | /* check CS non-audio bit and mute accordingly */ | ||
| 513 | if (avs.avs_cs_info[0] & 0x02) | ||
| 514 | ps3av_audio_mute_analog(1); /* mute if non-audio */ | ||
| 515 | else | ||
| 516 | ps3av_audio_mute_analog(0); | ||
| 517 | |||
| 518 | return ret; | ||
| 519 | } | ||
| 520 | |||
| 521 | /* | ||
| 385 | * PCM operators | 522 | * PCM operators |
| 386 | */ | 523 | */ |
| 387 | static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) | 524 | static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) |
| @@ -406,6 +543,13 @@ static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) | |||
| 406 | return 0; | 543 | return 0; |
| 407 | }; | 544 | }; |
| 408 | 545 | ||
| 546 | static int snd_ps3_pcm_close(struct snd_pcm_substream *substream) | ||
| 547 | { | ||
| 548 | /* mute on */ | ||
| 549 | snd_ps3_mute(1); | ||
| 550 | return 0; | ||
| 551 | }; | ||
| 552 | |||
| 409 | static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, | 553 | static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, |
| 410 | struct snd_pcm_hw_params *hw_params) | 554 | struct snd_pcm_hw_params *hw_params) |
| 411 | { | 555 | { |
| @@ -417,6 +561,13 @@ static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 417 | return 0; | 561 | return 0; |
| 418 | }; | 562 | }; |
| 419 | 563 | ||
| 564 | static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) | ||
| 565 | { | ||
| 566 | int ret; | ||
| 567 | ret = snd_pcm_lib_free_pages(substream); | ||
| 568 | return ret; | ||
| 569 | }; | ||
| 570 | |||
| 420 | static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, | 571 | static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, |
| 421 | unsigned int delay_ms) | 572 | unsigned int delay_ms) |
| 422 | { | 573 | { |
| @@ -556,202 +707,6 @@ static snd_pcm_uframes_t snd_ps3_pcm_pointer( | |||
| 556 | return ret; | 707 | return ret; |
| 557 | }; | 708 | }; |
| 558 | 709 | ||
| 559 | static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) | ||
| 560 | { | ||
| 561 | int ret; | ||
| 562 | ret = snd_pcm_lib_free_pages(substream); | ||
| 563 | return ret; | ||
| 564 | }; | ||
| 565 | |||
| 566 | static int snd_ps3_pcm_close(struct snd_pcm_substream *substream) | ||
| 567 | { | ||
| 568 | /* mute on */ | ||
| 569 | snd_ps3_mute(1); | ||
| 570 | return 0; | ||
| 571 | }; | ||
| 572 | |||
| 573 | static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card) | ||
| 574 | { | ||
| 575 | /* | ||
| 576 | * avsetting driver seems to never change the followings | ||
| 577 | * so, init them here once | ||
| 578 | */ | ||
| 579 | |||
| 580 | /* no dma interrupt needed */ | ||
| 581 | write_reg(PS3_AUDIO_INTR_EN_0, 0); | ||
| 582 | |||
| 583 | /* use every 4 buffer empty interrupt */ | ||
| 584 | update_mask_reg(PS3_AUDIO_AX_IC, | ||
| 585 | PS3_AUDIO_AX_IC_AASOIMD_MASK, | ||
| 586 | PS3_AUDIO_AX_IC_AASOIMD_EVERY4); | ||
| 587 | |||
| 588 | /* enable 3wire clocks */ | ||
| 589 | update_mask_reg(PS3_AUDIO_AO_3WMCTRL, | ||
| 590 | ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED | | ||
| 591 | PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED), | ||
| 592 | 0); | ||
| 593 | update_reg(PS3_AUDIO_AO_3WMCTRL, | ||
| 594 | PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT); | ||
| 595 | } | ||
| 596 | |||
| 597 | /* | ||
| 598 | * av setting | ||
| 599 | * NOTE: calling this function may generate audio interrupt. | ||
| 600 | */ | ||
| 601 | static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card) | ||
| 602 | { | ||
| 603 | int ret, retries, i; | ||
| 604 | pr_debug("%s: start\n", __func__); | ||
| 605 | |||
| 606 | ret = ps3av_set_audio_mode(card->avs.avs_audio_ch, | ||
| 607 | card->avs.avs_audio_rate, | ||
| 608 | card->avs.avs_audio_width, | ||
| 609 | card->avs.avs_audio_format, | ||
| 610 | card->avs.avs_audio_source); | ||
| 611 | /* | ||
| 612 | * Reset the following unwanted settings: | ||
| 613 | */ | ||
| 614 | |||
| 615 | /* disable all 3wire buffers */ | ||
| 616 | update_mask_reg(PS3_AUDIO_AO_3WMCTRL, | ||
| 617 | ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) | | ||
| 618 | PS3_AUDIO_AO_3WMCTRL_ASOEN(1) | | ||
| 619 | PS3_AUDIO_AO_3WMCTRL_ASOEN(2) | | ||
| 620 | PS3_AUDIO_AO_3WMCTRL_ASOEN(3)), | ||
| 621 | 0); | ||
| 622 | wmb(); /* ensure the hardware sees the change */ | ||
| 623 | /* wait for actually stopped */ | ||
| 624 | retries = 1000; | ||
| 625 | while ((read_reg(PS3_AUDIO_AO_3WMCTRL) & | ||
| 626 | (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | | ||
| 627 | PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | | ||
| 628 | PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | | ||
| 629 | PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) && | ||
| 630 | --retries) { | ||
| 631 | udelay(1); | ||
| 632 | } | ||
| 633 | |||
| 634 | /* reset buffer pointer */ | ||
| 635 | for (i = 0; i < 4; i++) { | ||
| 636 | update_reg(PS3_AUDIO_AO_3WCTRL(i), | ||
| 637 | PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET); | ||
| 638 | udelay(10); | ||
| 639 | } | ||
| 640 | wmb(); /* ensure the hardware actually start resetting */ | ||
| 641 | |||
| 642 | /* enable 3wire#0 buffer */ | ||
| 643 | update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0)); | ||
| 644 | |||
| 645 | |||
| 646 | /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */ | ||
| 647 | update_mask_reg(PS3_AUDIO_AO_3WCTRL(0), | ||
| 648 | ~PS3_AUDIO_AO_3WCTRL_ASODF, | ||
| 649 | PS3_AUDIO_AO_3WCTRL_ASODF_LSB); | ||
| 650 | update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0), | ||
| 651 | ~PS3_AUDIO_AO_SPDCTRL_SPODF, | ||
| 652 | PS3_AUDIO_AO_SPDCTRL_SPODF_LSB); | ||
| 653 | /* ensure all the setting above is written back to register */ | ||
| 654 | wmb(); | ||
| 655 | /* avsetting driver altered AX_IE, caller must reset it if you want */ | ||
| 656 | pr_debug("%s: end\n", __func__); | ||
| 657 | return ret; | ||
| 658 | } | ||
| 659 | |||
| 660 | static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card) | ||
| 661 | { | ||
| 662 | int ret; | ||
| 663 | pr_debug("%s: start\n", __func__); | ||
| 664 | card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; | ||
| 665 | card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; | ||
| 666 | card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; | ||
| 667 | card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; | ||
| 668 | card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; | ||
| 669 | memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8); | ||
| 670 | |||
| 671 | ret = snd_ps3_change_avsetting(card); | ||
| 672 | |||
| 673 | snd_ps3_audio_fixup(card); | ||
| 674 | |||
| 675 | /* to start to generate SPDIF signal, fill data */ | ||
| 676 | snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
| 677 | snd_ps3_kick_dma(card); | ||
| 678 | pr_debug("%s: end\n", __func__); | ||
| 679 | return ret; | ||
| 680 | } | ||
| 681 | |||
| 682 | /* | ||
| 683 | * set sampling rate according to the substream | ||
| 684 | */ | ||
| 685 | static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) | ||
| 686 | { | ||
| 687 | struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); | ||
| 688 | struct snd_ps3_avsetting_info avs; | ||
| 689 | int ret; | ||
| 690 | |||
| 691 | avs = card->avs; | ||
| 692 | |||
| 693 | pr_debug("%s: called freq=%d width=%d\n", __func__, | ||
| 694 | substream->runtime->rate, | ||
| 695 | snd_pcm_format_width(substream->runtime->format)); | ||
| 696 | |||
| 697 | pr_debug("%s: before freq=%d width=%d\n", __func__, | ||
| 698 | card->avs.avs_audio_rate, card->avs.avs_audio_width); | ||
| 699 | |||
| 700 | /* sample rate */ | ||
| 701 | switch (substream->runtime->rate) { | ||
| 702 | case 44100: | ||
| 703 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K; | ||
| 704 | break; | ||
| 705 | case 48000: | ||
| 706 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; | ||
| 707 | break; | ||
| 708 | case 88200: | ||
| 709 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K; | ||
| 710 | break; | ||
| 711 | case 96000: | ||
| 712 | avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K; | ||
| 713 | break; | ||
| 714 | default: | ||
| 715 | pr_info("%s: invalid rate %d\n", __func__, | ||
| 716 | substream->runtime->rate); | ||
| 717 | return 1; | ||
| 718 | } | ||
| 719 | |||
| 720 | /* width */ | ||
| 721 | switch (snd_pcm_format_width(substream->runtime->format)) { | ||
| 722 | case 16: | ||
| 723 | avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; | ||
| 724 | break; | ||
| 725 | case 24: | ||
| 726 | avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24; | ||
| 727 | break; | ||
| 728 | default: | ||
| 729 | pr_info("%s: invalid width %d\n", __func__, | ||
| 730 | snd_pcm_format_width(substream->runtime->format)); | ||
| 731 | return 1; | ||
| 732 | } | ||
| 733 | |||
| 734 | memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8); | ||
| 735 | |||
| 736 | if (memcmp(&card->avs, &avs, sizeof(avs))) { | ||
| 737 | pr_debug("%s: after freq=%d width=%d\n", __func__, | ||
| 738 | card->avs.avs_audio_rate, card->avs.avs_audio_width); | ||
| 739 | |||
| 740 | card->avs = avs; | ||
| 741 | snd_ps3_change_avsetting(card); | ||
| 742 | ret = 0; | ||
| 743 | } else | ||
| 744 | ret = 1; | ||
| 745 | |||
| 746 | /* check CS non-audio bit and mute accordingly */ | ||
| 747 | if (avs.avs_cs_info[0] & 0x02) | ||
| 748 | ps3av_audio_mute_analog(1); /* mute if non-audio */ | ||
| 749 | else | ||
| 750 | ps3av_audio_mute_analog(0); | ||
| 751 | |||
| 752 | return ret; | ||
| 753 | } | ||
| 754 | |||
| 755 | /* | 710 | /* |
| 756 | * SPDIF status bits controls | 711 | * SPDIF status bits controls |
| 757 | */ | 712 | */ |
| @@ -798,28 +753,39 @@ static struct snd_kcontrol_new spdif_ctls[] = { | |||
| 798 | { | 753 | { |
| 799 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 754 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 800 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 755 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 801 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), | 756 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), |
| 802 | .info = snd_ps3_spdif_mask_info, | 757 | .info = snd_ps3_spdif_mask_info, |
| 803 | .get = snd_ps3_spdif_cmask_get, | 758 | .get = snd_ps3_spdif_cmask_get, |
| 804 | }, | 759 | }, |
| 805 | { | 760 | { |
| 806 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 761 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 807 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 762 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 808 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), | 763 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), |
| 809 | .info = snd_ps3_spdif_mask_info, | 764 | .info = snd_ps3_spdif_mask_info, |
| 810 | .get = snd_ps3_spdif_pmask_get, | 765 | .get = snd_ps3_spdif_pmask_get, |
| 811 | }, | 766 | }, |
| 812 | { | 767 | { |
| 813 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 768 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 814 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 769 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), |
| 815 | .info = snd_ps3_spdif_mask_info, | 770 | .info = snd_ps3_spdif_mask_info, |
| 816 | .get = snd_ps3_spdif_default_get, | 771 | .get = snd_ps3_spdif_default_get, |
| 817 | .put = snd_ps3_spdif_default_put, | 772 | .put = snd_ps3_spdif_default_put, |
| 818 | }, | 773 | }, |
| 819 | }; | 774 | }; |
| 820 | 775 | ||
| 776 | static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = { | ||
| 777 | .open = snd_ps3_pcm_open, | ||
| 778 | .close = snd_ps3_pcm_close, | ||
| 779 | .ioctl = snd_pcm_lib_ioctl, | ||
| 780 | .hw_params = snd_ps3_pcm_hw_params, | ||
| 781 | .hw_free = snd_ps3_pcm_hw_free, | ||
| 782 | .prepare = snd_ps3_pcm_prepare, | ||
| 783 | .trigger = snd_ps3_pcm_trigger, | ||
| 784 | .pointer = snd_ps3_pcm_pointer, | ||
| 785 | }; | ||
| 786 | |||
| 821 | 787 | ||
| 822 | static int snd_ps3_map_mmio(void) | 788 | static int __devinit snd_ps3_map_mmio(void) |
| 823 | { | 789 | { |
| 824 | the_card.mapped_mmio_vaddr = | 790 | the_card.mapped_mmio_vaddr = |
| 825 | ioremap(the_card.ps3_dev->m_region->bus_addr, | 791 | ioremap(the_card.ps3_dev->m_region->bus_addr, |
| @@ -841,7 +807,7 @@ static void snd_ps3_unmap_mmio(void) | |||
| 841 | the_card.mapped_mmio_vaddr = NULL; | 807 | the_card.mapped_mmio_vaddr = NULL; |
| 842 | } | 808 | } |
| 843 | 809 | ||
| 844 | static int snd_ps3_allocate_irq(void) | 810 | static int __devinit snd_ps3_allocate_irq(void) |
| 845 | { | 811 | { |
| 846 | int ret; | 812 | int ret; |
| 847 | u64 lpar_addr, lpar_size; | 813 | u64 lpar_addr, lpar_size; |
| @@ -899,7 +865,7 @@ static void snd_ps3_free_irq(void) | |||
| 899 | ps3_irq_plug_destroy(the_card.irq_no); | 865 | ps3_irq_plug_destroy(the_card.irq_no); |
| 900 | } | 866 | } |
| 901 | 867 | ||
| 902 | static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) | 868 | static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) |
| 903 | { | 869 | { |
| 904 | uint64_t val; | 870 | uint64_t val; |
| 905 | int ret; | 871 | int ret; |
| @@ -915,7 +881,53 @@ static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) | |||
| 915 | ret); | 881 | ret); |
| 916 | } | 882 | } |
| 917 | 883 | ||
| 918 | static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | 884 | static void __devinit snd_ps3_audio_fixup(struct snd_ps3_card_info *card) |
| 885 | { | ||
| 886 | /* | ||
| 887 | * avsetting driver seems to never change the followings | ||
| 888 | * so, init them here once | ||
| 889 | */ | ||
| 890 | |||
| 891 | /* no dma interrupt needed */ | ||
| 892 | write_reg(PS3_AUDIO_INTR_EN_0, 0); | ||
| 893 | |||
| 894 | /* use every 4 buffer empty interrupt */ | ||
| 895 | update_mask_reg(PS3_AUDIO_AX_IC, | ||
| 896 | PS3_AUDIO_AX_IC_AASOIMD_MASK, | ||
| 897 | PS3_AUDIO_AX_IC_AASOIMD_EVERY4); | ||
| 898 | |||
| 899 | /* enable 3wire clocks */ | ||
| 900 | update_mask_reg(PS3_AUDIO_AO_3WMCTRL, | ||
| 901 | ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED | | ||
| 902 | PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED), | ||
| 903 | 0); | ||
| 904 | update_reg(PS3_AUDIO_AO_3WMCTRL, | ||
| 905 | PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT); | ||
| 906 | } | ||
| 907 | |||
| 908 | static int __devinit snd_ps3_init_avsetting(struct snd_ps3_card_info *card) | ||
| 909 | { | ||
| 910 | int ret; | ||
| 911 | pr_debug("%s: start\n", __func__); | ||
| 912 | card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; | ||
| 913 | card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; | ||
| 914 | card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; | ||
| 915 | card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; | ||
| 916 | card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; | ||
| 917 | memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8); | ||
| 918 | |||
| 919 | ret = snd_ps3_change_avsetting(card); | ||
| 920 | |||
| 921 | snd_ps3_audio_fixup(card); | ||
| 922 | |||
| 923 | /* to start to generate SPDIF signal, fill data */ | ||
| 924 | snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
| 925 | snd_ps3_kick_dma(card); | ||
| 926 | pr_debug("%s: end\n", __func__); | ||
| 927 | return ret; | ||
| 928 | } | ||
| 929 | |||
| 930 | static int __devinit snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | ||
| 919 | { | 931 | { |
| 920 | int i, ret; | 932 | int i, ret; |
| 921 | u64 lpar_addr, lpar_size; | 933 | u64 lpar_addr, lpar_size; |
| @@ -1020,11 +1032,12 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | |||
| 1020 | * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2 | 1032 | * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2 |
| 1021 | * PAGE_SIZE is enogh | 1033 | * PAGE_SIZE is enogh |
| 1022 | */ | 1034 | */ |
| 1023 | if (!(the_card.null_buffer_start_vaddr = | 1035 | the_card.null_buffer_start_vaddr = |
| 1024 | dma_alloc_coherent(&the_card.ps3_dev->core, | 1036 | dma_alloc_coherent(&the_card.ps3_dev->core, |
| 1025 | PAGE_SIZE, | 1037 | PAGE_SIZE, |
| 1026 | &the_card.null_buffer_start_dma_addr, | 1038 | &the_card.null_buffer_start_dma_addr, |
| 1027 | GFP_KERNEL))) { | 1039 | GFP_KERNEL); |
| 1040 | if (!the_card.null_buffer_start_vaddr) { | ||
| 1028 | pr_info("%s: nullbuffer alloc failed\n", __func__); | 1041 | pr_info("%s: nullbuffer alloc failed\n", __func__); |
| 1029 | goto clean_preallocate; | 1042 | goto clean_preallocate; |
| 1030 | } | 1043 | } |
| @@ -1115,71 +1128,6 @@ static struct ps3_system_bus_driver snd_ps3_bus_driver_info = { | |||
| 1115 | 1128 | ||
| 1116 | 1129 | ||
| 1117 | /* | 1130 | /* |
| 1118 | * Interrupt handler | ||
| 1119 | */ | ||
| 1120 | static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id) | ||
| 1121 | { | ||
| 1122 | |||
| 1123 | uint32_t port_intr; | ||
| 1124 | int underflow_occured = 0; | ||
| 1125 | struct snd_ps3_card_info *card = dev_id; | ||
| 1126 | |||
| 1127 | if (!card->running) { | ||
| 1128 | update_reg(PS3_AUDIO_AX_IS, 0); | ||
| 1129 | update_reg(PS3_AUDIO_INTR_0, 0); | ||
| 1130 | return IRQ_HANDLED; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | port_intr = read_reg(PS3_AUDIO_AX_IS); | ||
| 1134 | /* | ||
| 1135 | *serial buffer empty detected (every 4 times), | ||
| 1136 | *program next dma and kick it | ||
| 1137 | */ | ||
| 1138 | if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) { | ||
| 1139 | write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0)); | ||
| 1140 | if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { | ||
| 1141 | write_reg(PS3_AUDIO_AX_IS, port_intr); | ||
| 1142 | underflow_occured = 1; | ||
| 1143 | } | ||
| 1144 | if (card->silent) { | ||
| 1145 | /* we are still in silent time */ | ||
| 1146 | snd_ps3_program_dma(card, | ||
| 1147 | (underflow_occured) ? | ||
| 1148 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL : | ||
| 1149 | SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); | ||
| 1150 | snd_ps3_kick_dma(card); | ||
| 1151 | card->silent --; | ||
| 1152 | } else { | ||
| 1153 | snd_ps3_program_dma(card, | ||
| 1154 | (underflow_occured) ? | ||
| 1155 | SND_PS3_DMA_FILLTYPE_FIRSTFILL : | ||
| 1156 | SND_PS3_DMA_FILLTYPE_RUNNING); | ||
| 1157 | snd_ps3_kick_dma(card); | ||
| 1158 | snd_pcm_period_elapsed(card->substream); | ||
| 1159 | } | ||
| 1160 | } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { | ||
| 1161 | write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0)); | ||
| 1162 | /* | ||
| 1163 | * serial out underflow, but buffer empty not detected. | ||
| 1164 | * in this case, fill fifo with 0 to recover. After | ||
| 1165 | * filling dummy data, serial automatically start to | ||
| 1166 | * consume them and then will generate normal buffer | ||
| 1167 | * empty interrupts. | ||
| 1168 | * If both buffer underflow and buffer empty are occured, | ||
| 1169 | * it is better to do nomal data transfer than empty one | ||
| 1170 | */ | ||
| 1171 | snd_ps3_program_dma(card, | ||
| 1172 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
| 1173 | snd_ps3_kick_dma(card); | ||
| 1174 | snd_ps3_program_dma(card, | ||
| 1175 | SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); | ||
| 1176 | snd_ps3_kick_dma(card); | ||
| 1177 | } | ||
| 1178 | /* clear interrupt cause */ | ||
| 1179 | return IRQ_HANDLED; | ||
| 1180 | }; | ||
| 1181 | |||
| 1182 | /* | ||
| 1183 | * module/subsystem initialize/terminate | 1131 | * module/subsystem initialize/terminate |
| 1184 | */ | 1132 | */ |
| 1185 | static int __init snd_ps3_init(void) | 1133 | static int __init snd_ps3_init(void) |
| @@ -1197,10 +1145,15 @@ static int __init snd_ps3_init(void) | |||
| 1197 | 1145 | ||
| 1198 | return ret; | 1146 | return ret; |
| 1199 | } | 1147 | } |
| 1148 | module_init(snd_ps3_init); | ||
| 1200 | 1149 | ||
| 1201 | static void __exit snd_ps3_exit(void) | 1150 | static void __exit snd_ps3_exit(void) |
| 1202 | { | 1151 | { |
| 1203 | ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); | 1152 | ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); |
| 1204 | } | 1153 | } |
| 1154 | module_exit(snd_ps3_exit); | ||
| 1205 | 1155 | ||
| 1156 | MODULE_LICENSE("GPL v2"); | ||
| 1157 | MODULE_DESCRIPTION("PS3 sound driver"); | ||
| 1158 | MODULE_AUTHOR("Sony Computer Entertainment Inc."); | ||
| 1206 | MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); | 1159 | MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); |
