aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorGeert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>2009-06-10 10:39:02 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-10 10:53:09 -0400
commitcb6492e4a4e68281358510f0ffe2b0c4972ec166 (patch)
tree09cf532a7486d52e3b69698f0dc2d170dcea2e15 /sound
parent112ac808eb8a953dd356bbbc8322fdd6861e2c75 (diff)
ALSA: sound/ps3: Restructure driver source
Sort includes, and reorder code so we can kill the forward declarations No functional changes Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/ppc/snd_ps3.c621
1 files changed, 288 insertions, 333 deletions
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index d660b0f6bca..cd9109aaa55 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -18,80 +18,30 @@
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"
43#include "snd_ps3_reg.h"
42 44
43MODULE_LICENSE("GPL v2");
44MODULE_DESCRIPTION("PS3 sound driver");
45MODULE_AUTHOR("Sony Computer Entertainment Inc.");
46
47/* module entries */
48static int __init snd_ps3_init(void);
49static void __exit snd_ps3_exit(void);
50
51/* ALSA snd driver ops */
52static int snd_ps3_pcm_open(struct snd_pcm_substream *substream);
53static int snd_ps3_pcm_close(struct snd_pcm_substream *substream);
54static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream);
55static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream,
56 int cmd);
57static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream
58 *substream);
59static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream,
60 struct snd_pcm_hw_params *hw_params);
61static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream);
62
63
64/* ps3_system_bus_driver entries */
65static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev);
66static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev);
67
68/* address setup */
69static int snd_ps3_map_mmio(void);
70static void snd_ps3_unmap_mmio(void);
71static int snd_ps3_allocate_irq(void);
72static void snd_ps3_free_irq(void);
73static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start);
74
75/* interrupt handler */
76static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id);
77
78
79/* set sampling rate/format */
80static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream);
81/* take effect parameter change */
82static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card);
83/* initialize avsetting and take it effect */
84static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card);
85/* setup dma */
86static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
87 enum snd_ps3_dma_filltype filltype);
88static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card);
89
90static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void *vaddr, int ch);
91
92
93module_init(snd_ps3_init);
94module_exit(snd_ps3_exit);
95 45
96/* 46/*
97 * global 47 * global
@@ -165,17 +115,6 @@ 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
168static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = {
169 .open = snd_ps3_pcm_open,
170 .close = snd_ps3_pcm_close,
171 .prepare = snd_ps3_pcm_prepare,
172 .ioctl = snd_pcm_lib_ioctl,
173 .trigger = snd_ps3_pcm_trigger,
174 .pointer = snd_ps3_pcm_pointer,
175 .hw_params = snd_ps3_pcm_hw_params,
176 .hw_free = snd_ps3_pcm_hw_free
177};
178
179static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card, 118static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card,
180 int count, int force_stop) 119 int count, int force_stop)
181{ 120{
@@ -369,6 +308,71 @@ static int snd_ps3_program_dma(struct snd_ps3_card_info *card,
369} 308}
370 309
371/* 310/*
311 * Interrupt handler
312 */
313static 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/*
372 * audio mute on/off 376 * audio mute on/off
373 * mute_on : 0 output enabled 377 * mute_on : 0 output enabled
374 * 1 mute 378 * 1 mute
@@ -379,6 +383,142 @@ static int snd_ps3_mute(int mute_on)
379} 383}
380 384
381/* 385/*
386 * av setting
387 * NOTE: calling this function may generate audio interrupt.
388 */
389static 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 */
451static 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/*
382 * PCM operators 522 * PCM operators
383 */ 523 */
384static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) 524static int snd_ps3_pcm_open(struct snd_pcm_substream *substream)
@@ -403,6 +543,13 @@ static int snd_ps3_pcm_open(struct snd_pcm_substream *substream)
403 return 0; 543 return 0;
404}; 544};
405 545
546static int snd_ps3_pcm_close(struct snd_pcm_substream *substream)
547{
548 /* mute on */
549 snd_ps3_mute(1);
550 return 0;
551};
552
406static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, 553static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream,
407 struct snd_pcm_hw_params *hw_params) 554 struct snd_pcm_hw_params *hw_params)
408{ 555{
@@ -414,6 +561,13 @@ static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream,
414 return 0; 561 return 0;
415}; 562};
416 563
564static 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
417static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, 571static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream,
418 unsigned int delay_ms) 572 unsigned int delay_ms)
419{ 573{
@@ -553,202 +707,6 @@ static snd_pcm_uframes_t snd_ps3_pcm_pointer(
553 return ret; 707 return ret;
554}; 708};
555 709
556static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream)
557{
558 int ret;
559 ret = snd_pcm_lib_free_pages(substream);
560 return ret;
561};
562
563static int snd_ps3_pcm_close(struct snd_pcm_substream *substream)
564{
565 /* mute on */
566 snd_ps3_mute(1);
567 return 0;
568};
569
570static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card)
571{
572 /*
573 * avsetting driver seems to never change the followings
574 * so, init them here once
575 */
576
577 /* no dma interrupt needed */
578 write_reg(PS3_AUDIO_INTR_EN_0, 0);
579
580 /* use every 4 buffer empty interrupt */
581 update_mask_reg(PS3_AUDIO_AX_IC,
582 PS3_AUDIO_AX_IC_AASOIMD_MASK,
583 PS3_AUDIO_AX_IC_AASOIMD_EVERY4);
584
585 /* enable 3wire clocks */
586 update_mask_reg(PS3_AUDIO_AO_3WMCTRL,
587 ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED |
588 PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED),
589 0);
590 update_reg(PS3_AUDIO_AO_3WMCTRL,
591 PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT);
592}
593
594/*
595 * av setting
596 * NOTE: calling this function may generate audio interrupt.
597 */
598static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card)
599{
600 int ret, retries, i;
601 pr_debug("%s: start\n", __func__);
602
603 ret = ps3av_set_audio_mode(card->avs.avs_audio_ch,
604 card->avs.avs_audio_rate,
605 card->avs.avs_audio_width,
606 card->avs.avs_audio_format,
607 card->avs.avs_audio_source);
608 /*
609 * Reset the following unwanted settings:
610 */
611
612 /* disable all 3wire buffers */
613 update_mask_reg(PS3_AUDIO_AO_3WMCTRL,
614 ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) |
615 PS3_AUDIO_AO_3WMCTRL_ASOEN(1) |
616 PS3_AUDIO_AO_3WMCTRL_ASOEN(2) |
617 PS3_AUDIO_AO_3WMCTRL_ASOEN(3)),
618 0);
619 wmb(); /* ensure the hardware sees the change */
620 /* wait for actually stopped */
621 retries = 1000;
622 while ((read_reg(PS3_AUDIO_AO_3WMCTRL) &
623 (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) |
624 PS3_AUDIO_AO_3WMCTRL_ASORUN(1) |
625 PS3_AUDIO_AO_3WMCTRL_ASORUN(2) |
626 PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) &&
627 --retries) {
628 udelay(1);
629 }
630
631 /* reset buffer pointer */
632 for (i = 0; i < 4; i++) {
633 update_reg(PS3_AUDIO_AO_3WCTRL(i),
634 PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET);
635 udelay(10);
636 }
637 wmb(); /* ensure the hardware actually start resetting */
638
639 /* enable 3wire#0 buffer */
640 update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0));
641
642
643 /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */
644 update_mask_reg(PS3_AUDIO_AO_3WCTRL(0),
645 ~PS3_AUDIO_AO_3WCTRL_ASODF,
646 PS3_AUDIO_AO_3WCTRL_ASODF_LSB);
647 update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0),
648 ~PS3_AUDIO_AO_SPDCTRL_SPODF,
649 PS3_AUDIO_AO_SPDCTRL_SPODF_LSB);
650 /* ensure all the setting above is written back to register */
651 wmb();
652 /* avsetting driver altered AX_IE, caller must reset it if you want */
653 pr_debug("%s: end\n", __func__);
654 return ret;
655}
656
657static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
658{
659 int ret;
660 pr_debug("%s: start\n", __func__);
661 card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2;
662 card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K;
663 card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
664 card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM;
665 card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
666 memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8);
667
668 ret = snd_ps3_change_avsetting(card);
669
670 snd_ps3_audio_fixup(card);
671
672 /* to start to generate SPDIF signal, fill data */
673 snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
674 snd_ps3_kick_dma(card);
675 pr_debug("%s: end\n", __func__);
676 return ret;
677}
678
679/*
680 * set sampling rate according to the substream
681 */
682static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
683{
684 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
685 struct snd_ps3_avsetting_info avs;
686 int ret;
687
688 avs = card->avs;
689
690 pr_debug("%s: called freq=%d width=%d\n", __func__,
691 substream->runtime->rate,
692 snd_pcm_format_width(substream->runtime->format));
693
694 pr_debug("%s: before freq=%d width=%d\n", __func__,
695 card->avs.avs_audio_rate, card->avs.avs_audio_width);
696
697 /* sample rate */
698 switch (substream->runtime->rate) {
699 case 44100:
700 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K;
701 break;
702 case 48000:
703 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K;
704 break;
705 case 88200:
706 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K;
707 break;
708 case 96000:
709 avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K;
710 break;
711 default:
712 pr_info("%s: invalid rate %d\n", __func__,
713 substream->runtime->rate);
714 return 1;
715 }
716
717 /* width */
718 switch (snd_pcm_format_width(substream->runtime->format)) {
719 case 16:
720 avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
721 break;
722 case 24:
723 avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24;
724 break;
725 default:
726 pr_info("%s: invalid width %d\n", __func__,
727 snd_pcm_format_width(substream->runtime->format));
728 return 1;
729 }
730
731 memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8);
732
733 if (memcmp(&card->avs, &avs, sizeof(avs))) {
734 pr_debug("%s: after freq=%d width=%d\n", __func__,
735 card->avs.avs_audio_rate, card->avs.avs_audio_width);
736
737 card->avs = avs;
738 snd_ps3_change_avsetting(card);
739 ret = 0;
740 } else
741 ret = 1;
742
743 /* check CS non-audio bit and mute accordingly */
744 if (avs.avs_cs_info[0] & 0x02)
745 ps3av_audio_mute_analog(1); /* mute if non-audio */
746 else
747 ps3av_audio_mute_analog(0);
748
749 return ret;
750}
751
752/* 710/*
753 * SPDIF status bits controls 711 * SPDIF status bits controls
754 */ 712 */
@@ -815,6 +773,17 @@ static struct snd_kcontrol_new spdif_ctls[] = {
815 }, 773 },
816}; 774};
817 775
776static 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
818 787
819static int snd_ps3_map_mmio(void) 788static int snd_ps3_map_mmio(void)
820{ 789{
@@ -912,6 +881,52 @@ static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
912 ret); 881 ret);
913} 882}
914 883
884static void 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
908static int 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
915static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) 930static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
916{ 931{
917 int i, ret; 932 int i, ret;
@@ -1113,71 +1128,6 @@ static struct ps3_system_bus_driver snd_ps3_bus_driver_info = {
1113 1128
1114 1129
1115/* 1130/*
1116 * Interrupt handler
1117 */
1118static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id)
1119{
1120
1121 uint32_t port_intr;
1122 int underflow_occured = 0;
1123 struct snd_ps3_card_info *card = dev_id;
1124
1125 if (!card->running) {
1126 update_reg(PS3_AUDIO_AX_IS, 0);
1127 update_reg(PS3_AUDIO_INTR_0, 0);
1128 return IRQ_HANDLED;
1129 }
1130
1131 port_intr = read_reg(PS3_AUDIO_AX_IS);
1132 /*
1133 *serial buffer empty detected (every 4 times),
1134 *program next dma and kick it
1135 */
1136 if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) {
1137 write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0));
1138 if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) {
1139 write_reg(PS3_AUDIO_AX_IS, port_intr);
1140 underflow_occured = 1;
1141 }
1142 if (card->silent) {
1143 /* we are still in silent time */
1144 snd_ps3_program_dma(card,
1145 (underflow_occured) ?
1146 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL :
1147 SND_PS3_DMA_FILLTYPE_SILENT_RUNNING);
1148 snd_ps3_kick_dma(card);
1149 card->silent--;
1150 } else {
1151 snd_ps3_program_dma(card,
1152 (underflow_occured) ?
1153 SND_PS3_DMA_FILLTYPE_FIRSTFILL :
1154 SND_PS3_DMA_FILLTYPE_RUNNING);
1155 snd_ps3_kick_dma(card);
1156 snd_pcm_period_elapsed(card->substream);
1157 }
1158 } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) {
1159 write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0));
1160 /*
1161 * serial out underflow, but buffer empty not detected.
1162 * in this case, fill fifo with 0 to recover. After
1163 * filling dummy data, serial automatically start to
1164 * consume them and then will generate normal buffer
1165 * empty interrupts.
1166 * If both buffer underflow and buffer empty are occured,
1167 * it is better to do nomal data transfer than empty one
1168 */
1169 snd_ps3_program_dma(card,
1170 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
1171 snd_ps3_kick_dma(card);
1172 snd_ps3_program_dma(card,
1173 SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL);
1174 snd_ps3_kick_dma(card);
1175 }
1176 /* clear interrupt cause */
1177 return IRQ_HANDLED;
1178};
1179
1180/*
1181 * module/subsystem initialize/terminate 1131 * module/subsystem initialize/terminate
1182 */ 1132 */
1183static int __init snd_ps3_init(void) 1133static int __init snd_ps3_init(void)
@@ -1195,10 +1145,15 @@ static int __init snd_ps3_init(void)
1195 1145
1196 return ret; 1146 return ret;
1197} 1147}
1148module_init(snd_ps3_init);
1198 1149
1199static void __exit snd_ps3_exit(void) 1150static void __exit snd_ps3_exit(void)
1200{ 1151{
1201 ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); 1152 ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info);
1202} 1153}
1154module_exit(snd_ps3_exit);
1203 1155
1156MODULE_LICENSE("GPL v2");
1157MODULE_DESCRIPTION("PS3 sound driver");
1158MODULE_AUTHOR("Sony Computer Entertainment Inc.");
1204MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); 1159MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND);