diff options
Diffstat (limited to 'sound/ppc/snd_ps3.c')
-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); |