aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-06-26 10:50:16 -0400
committerTakashi Iwai <tiwai@suse.de>2014-06-26 12:00:01 -0400
commitb6050ef664219a0bc97d0626759ef070ed77fcba (patch)
tree2a69c2b96d819a324ea132f2b938b4dd01a3e88d /sound
parent085ec0d945cd52caba3765e4cbcfe24cc136e905 (diff)
ALSA: hda - Make position_fix as generic callback
... and move most parts into hda_intel.c from the generic controller code. This is a clean up, and there should be no functional change by this patch. Now, struct azx obtains the generic callbacks for getting the position and the delay. As default NULL, posbuf is read. These replace the old position_fix[], and each is implemented as a callback. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_controller.c127
-rw-r--r--sound/pci/hda/hda_controller.h6
-rw-r--r--sound/pci/hda/hda_intel.c151
-rw-r--r--sound/pci/hda/hda_priv.h17
-rw-r--r--sound/pci/hda/hda_tegra.c2
5 files changed, 174 insertions, 129 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 875e0ebf56eb..a562d86c02fb 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -152,8 +152,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
152 upper_32_bits(azx_dev->bdl.addr)); 152 upper_32_bits(azx_dev->bdl.addr));
153 153
154 /* enable the position buffer */ 154 /* enable the position buffer */
155 if (chip->position_fix[0] != POS_FIX_LPIB || 155 if (chip->get_position[0] != azx_get_pos_lpib ||
156 chip->position_fix[1] != POS_FIX_LPIB) { 156 chip->get_position[1] != azx_get_pos_lpib) {
157 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 157 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
158 azx_writel(chip, DPLBASE, 158 azx_writel(chip, DPLBASE,
159 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); 159 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
@@ -673,125 +673,40 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
673 return 0; 673 return 0;
674} 674}
675 675
676/* get the current DMA position with correction on VIA chips */ 676unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev)
677static unsigned int azx_via_get_position(struct azx *chip,
678 struct azx_dev *azx_dev)
679{ 677{
680 unsigned int link_pos, mini_pos, bound_pos; 678 return azx_sd_readl(chip, azx_dev, SD_LPIB);
681 unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos; 679}
682 unsigned int fifo_size; 680EXPORT_SYMBOL_GPL(azx_get_pos_lpib);
683
684 link_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
685 if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
686 /* Playback, no problem using link position */
687 return link_pos;
688 }
689
690 /* Capture */
691 /* For new chipset,
692 * use mod to get the DMA position just like old chipset
693 */
694 mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
695 mod_dma_pos %= azx_dev->period_bytes;
696
697 /* azx_dev->fifo_size can't get FIFO size of in stream.
698 * Get from base address + offset.
699 */
700 fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
701
702 if (azx_dev->insufficient) {
703 /* Link position never gather than FIFO size */
704 if (link_pos <= fifo_size)
705 return 0;
706
707 azx_dev->insufficient = 0;
708 }
709
710 if (link_pos <= fifo_size)
711 mini_pos = azx_dev->bufsize + link_pos - fifo_size;
712 else
713 mini_pos = link_pos - fifo_size;
714
715 /* Find nearest previous boudary */
716 mod_mini_pos = mini_pos % azx_dev->period_bytes;
717 mod_link_pos = link_pos % azx_dev->period_bytes;
718 if (mod_link_pos >= fifo_size)
719 bound_pos = link_pos - mod_link_pos;
720 else if (mod_dma_pos >= mod_mini_pos)
721 bound_pos = mini_pos - mod_mini_pos;
722 else {
723 bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
724 if (bound_pos >= azx_dev->bufsize)
725 bound_pos = 0;
726 }
727 681
728 /* Calculate real DMA position we want */ 682unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev)
729 return bound_pos + mod_dma_pos; 683{
684 return le32_to_cpu(*azx_dev->posbuf);
730} 685}
686EXPORT_SYMBOL_GPL(azx_get_pos_posbuf);
731 687
732unsigned int azx_get_position(struct azx *chip, 688unsigned int azx_get_position(struct azx *chip,
733 struct azx_dev *azx_dev, 689 struct azx_dev *azx_dev)
734 bool with_check)
735{ 690{
736 struct snd_pcm_substream *substream = azx_dev->substream; 691 struct snd_pcm_substream *substream = azx_dev->substream;
737 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
738 unsigned int pos; 692 unsigned int pos;
739 int stream = substream->stream; 693 int stream = substream->stream;
740 struct hda_pcm_stream *hinfo = apcm->hinfo[stream];
741 int delay = 0; 694 int delay = 0;
742 695
743 switch (chip->position_fix[stream]) { 696 if (chip->get_position[stream])
744 case POS_FIX_LPIB: 697 pos = chip->get_position[stream](chip, azx_dev);
745 /* read LPIB */ 698 else /* use the position buffer as default */
746 pos = azx_sd_readl(chip, azx_dev, SD_LPIB); 699 pos = azx_get_pos_posbuf(chip, azx_dev);
747 break;
748 case POS_FIX_VIACOMBO:
749 pos = azx_via_get_position(chip, azx_dev);
750 break;
751 default:
752 /* use the position buffer */
753 pos = le32_to_cpu(*azx_dev->posbuf);
754 if (with_check && chip->position_fix[stream] == POS_FIX_AUTO) {
755 if (!pos || pos == (u32)-1) {
756 dev_info(chip->card->dev,
757 "Invalid position buffer, using LPIB read method instead.\n");
758 chip->position_fix[stream] = POS_FIX_LPIB;
759 pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
760 } else
761 chip->position_fix[stream] = POS_FIX_POSBUF;
762 }
763 break;
764 }
765 700
766 if (pos >= azx_dev->bufsize) 701 if (pos >= azx_dev->bufsize)
767 pos = 0; 702 pos = 0;
768 703
769 /* calculate runtime delay from LPIB */
770 if (substream->runtime &&
771 chip->position_fix[stream] == POS_FIX_POSBUF &&
772 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
773 unsigned int lpib_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
774 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
775 delay = pos - lpib_pos;
776 else
777 delay = lpib_pos - pos;
778 if (delay < 0) {
779 if (delay >= azx_dev->delay_negative_threshold)
780 delay = 0;
781 else
782 delay += azx_dev->bufsize;
783 }
784 if (delay >= azx_dev->period_bytes) {
785 dev_info(chip->card->dev,
786 "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
787 delay, azx_dev->period_bytes);
788 delay = 0;
789 chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
790 }
791 delay = bytes_to_frames(substream->runtime, delay);
792 }
793
794 if (substream->runtime) { 704 if (substream->runtime) {
705 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
706 struct hda_pcm_stream *hinfo = apcm->hinfo[stream];
707
708 if (chip->get_delay[stream])
709 delay += chip->get_delay[stream](chip, azx_dev, pos);
795 if (hinfo->ops.get_delay) 710 if (hinfo->ops.get_delay)
796 delay += hinfo->ops.get_delay(hinfo, apcm->codec, 711 delay += hinfo->ops.get_delay(hinfo, apcm->codec,
797 substream); 712 substream);
@@ -809,7 +724,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
809 struct azx *chip = apcm->chip; 724 struct azx *chip = apcm->chip;
810 struct azx_dev *azx_dev = get_azx_dev(substream); 725 struct azx_dev *azx_dev = get_azx_dev(substream);
811 return bytes_to_frames(substream->runtime, 726 return bytes_to_frames(substream->runtime,
812 azx_get_position(chip, azx_dev, false)); 727 azx_get_position(chip, azx_dev));
813} 728}
814 729
815static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream, 730static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index baf0e77330af..91f04958e2b0 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -25,9 +25,9 @@ static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream)
25{ 25{
26 return substream->runtime->private_data; 26 return substream->runtime->private_data;
27} 27}
28unsigned int azx_get_position(struct azx *chip, 28unsigned int azx_get_position(struct azx *chip, struct azx_dev *azx_dev);
29 struct azx_dev *azx_dev, 29unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev);
30 bool with_check); 30unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev);
31 31
32/* Stream control. */ 32/* Stream control. */
33void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev); 33void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 25753db97071..cb5d807bbd0c 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -66,6 +66,15 @@
66#include "hda_controller.h" 66#include "hda_controller.h"
67#include "hda_priv.h" 67#include "hda_priv.h"
68 68
69/* position fix mode */
70enum {
71 POS_FIX_AUTO,
72 POS_FIX_LPIB,
73 POS_FIX_POSBUF,
74 POS_FIX_VIACOMBO,
75 POS_FIX_COMBO,
76};
77
69 78
70static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 79static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
71static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 80static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -434,6 +443,38 @@ static void azx_init_pci(struct azx *chip)
434 } 443 }
435} 444}
436 445
446/* calculate runtime delay from LPIB */
447static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev,
448 unsigned int pos)
449{
450 struct snd_pcm_substream *substream = azx_dev->substream;
451 int stream = substream->stream;
452 unsigned int lpib_pos = azx_get_pos_lpib(chip, azx_dev);
453 int delay;
454
455 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
456 delay = pos - lpib_pos;
457 else
458 delay = lpib_pos - pos;
459 if (delay < 0) {
460 if (delay >= azx_dev->delay_negative_threshold)
461 delay = 0;
462 else
463 delay += azx_dev->bufsize;
464 }
465
466 if (delay >= azx_dev->period_bytes) {
467 dev_info(chip->card->dev,
468 "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
469 delay, azx_dev->period_bytes);
470 delay = 0;
471 chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
472 chip->get_delay[stream] = NULL;
473 }
474
475 return bytes_to_frames(substream->runtime, delay);
476}
477
437static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); 478static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
438 479
439/* called from IRQ */ 480/* called from IRQ */
@@ -464,6 +505,8 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
464 */ 505 */
465static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) 506static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
466{ 507{
508 struct snd_pcm_substream *substream = azx_dev->substream;
509 int stream = substream->stream;
467 u32 wallclk; 510 u32 wallclk;
468 unsigned int pos; 511 unsigned int pos;
469 512
@@ -471,7 +514,25 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
471 if (wallclk < (azx_dev->period_wallclk * 2) / 3) 514 if (wallclk < (azx_dev->period_wallclk * 2) / 3)
472 return -1; /* bogus (too early) interrupt */ 515 return -1; /* bogus (too early) interrupt */
473 516
474 pos = azx_get_position(chip, azx_dev, true); 517 if (chip->get_position[stream])
518 pos = chip->get_position[stream](chip, azx_dev);
519 else { /* use the position buffer as default */
520 pos = azx_get_pos_posbuf(chip, azx_dev);
521 if (!pos || pos == (u32)-1) {
522 dev_info(chip->card->dev,
523 "Invalid position buffer, using LPIB read method instead.\n");
524 chip->get_position[stream] = azx_get_pos_lpib;
525 pos = azx_get_pos_lpib(chip, azx_dev);
526 chip->get_delay[stream] = NULL;
527 } else {
528 chip->get_position[stream] = azx_get_pos_posbuf;
529 if (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)
530 chip->get_delay[stream] = azx_get_delay_from_lpib;
531 }
532 }
533
534 if (pos >= azx_dev->bufsize)
535 pos = 0;
475 536
476 if (WARN_ONCE(!azx_dev->period_bytes, 537 if (WARN_ONCE(!azx_dev->period_bytes,
477 "hda-intel: zero azx_dev->period_bytes")) 538 "hda-intel: zero azx_dev->period_bytes"))
@@ -554,6 +615,62 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
554 return 0; 615 return 0;
555} 616}
556 617
618/* get the current DMA position with correction on VIA chips */
619static unsigned int azx_via_get_position(struct azx *chip,
620 struct azx_dev *azx_dev)
621{
622 unsigned int link_pos, mini_pos, bound_pos;
623 unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
624 unsigned int fifo_size;
625
626 link_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
627 if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
628 /* Playback, no problem using link position */
629 return link_pos;
630 }
631
632 /* Capture */
633 /* For new chipset,
634 * use mod to get the DMA position just like old chipset
635 */
636 mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
637 mod_dma_pos %= azx_dev->period_bytes;
638
639 /* azx_dev->fifo_size can't get FIFO size of in stream.
640 * Get from base address + offset.
641 */
642 fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
643
644 if (azx_dev->insufficient) {
645 /* Link position never gather than FIFO size */
646 if (link_pos <= fifo_size)
647 return 0;
648
649 azx_dev->insufficient = 0;
650 }
651
652 if (link_pos <= fifo_size)
653 mini_pos = azx_dev->bufsize + link_pos - fifo_size;
654 else
655 mini_pos = link_pos - fifo_size;
656
657 /* Find nearest previous boudary */
658 mod_mini_pos = mini_pos % azx_dev->period_bytes;
659 mod_link_pos = link_pos % azx_dev->period_bytes;
660 if (mod_link_pos >= fifo_size)
661 bound_pos = link_pos - mod_link_pos;
662 else if (mod_dma_pos >= mod_mini_pos)
663 bound_pos = mini_pos - mod_mini_pos;
664 else {
665 bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
666 if (bound_pos >= azx_dev->bufsize)
667 bound_pos = 0;
668 }
669
670 /* Calculate real DMA position we want */
671 return bound_pos + mod_dma_pos;
672}
673
557#ifdef CONFIG_PM 674#ifdef CONFIG_PM
558static DEFINE_MUTEX(card_list_lock); 675static DEFINE_MUTEX(card_list_lock);
559static LIST_HEAD(card_list); 676static LIST_HEAD(card_list);
@@ -1084,6 +1201,30 @@ static int check_position_fix(struct azx *chip, int fix)
1084 return POS_FIX_AUTO; 1201 return POS_FIX_AUTO;
1085} 1202}
1086 1203
1204static void assign_position_fix(struct azx *chip, int fix)
1205{
1206 static azx_get_pos_callback_t callbacks[] = {
1207 [POS_FIX_AUTO] = NULL,
1208 [POS_FIX_LPIB] = azx_get_pos_lpib,
1209 [POS_FIX_POSBUF] = azx_get_pos_posbuf,
1210 [POS_FIX_VIACOMBO] = azx_via_get_position,
1211 [POS_FIX_COMBO] = azx_get_pos_lpib,
1212 };
1213
1214 chip->get_position[0] = chip->get_position[1] = callbacks[fix];
1215
1216 /* combo mode uses LPIB only for playback */
1217 if (fix == POS_FIX_COMBO)
1218 chip->get_position[1] = NULL;
1219
1220 if (fix == POS_FIX_POSBUF &&
1221 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
1222 chip->get_delay[0] = chip->get_delay[1] =
1223 azx_get_delay_from_lpib;
1224 }
1225
1226}
1227
1087/* 1228/*
1088 * black-lists for probe_mask 1229 * black-lists for probe_mask
1089 */ 1230 */
@@ -1258,13 +1399,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
1258 init_vga_switcheroo(chip); 1399 init_vga_switcheroo(chip);
1259 init_completion(&chip->probe_wait); 1400 init_completion(&chip->probe_wait);
1260 1401
1261 chip->position_fix[0] = chip->position_fix[1] = 1402 assign_position_fix(chip, check_position_fix(chip, position_fix[dev]));
1262 check_position_fix(chip, position_fix[dev]);
1263 /* combo mode uses LPIB for playback */
1264 if (chip->position_fix[0] == POS_FIX_COMBO) {
1265 chip->position_fix[0] = POS_FIX_LPIB;
1266 chip->position_fix[1] = POS_FIX_AUTO;
1267 }
1268 1403
1269 check_probe_mask(chip, dev); 1404 check_probe_mask(chip, dev);
1270 1405
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h
index da12d10b778f..43dd8a19cc09 100644
--- a/sound/pci/hda/hda_priv.h
+++ b/sound/pci/hda/hda_priv.h
@@ -188,15 +188,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
188#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ 188#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */
189#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ 189#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
190 190
191/* position fix mode */
192enum {
193 POS_FIX_AUTO,
194 POS_FIX_LPIB,
195 POS_FIX_POSBUF,
196 POS_FIX_VIACOMBO,
197 POS_FIX_COMBO,
198};
199
200/* Defines for ATI HD Audio support in SB450 south bridge */ 191/* Defines for ATI HD Audio support in SB450 south bridge */
201#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 192#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
202#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 193#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
@@ -321,6 +312,9 @@ struct azx_pcm {
321 struct list_head list; 312 struct list_head list;
322}; 313};
323 314
315typedef unsigned int (*azx_get_pos_callback_t)(struct azx *, struct azx_dev *);
316typedef int (*azx_get_delay_callback_t)(struct azx *, struct azx_dev *, unsigned int pos);
317
324struct azx { 318struct azx {
325 struct snd_card *card; 319 struct snd_card *card;
326 struct pci_dev *pci; 320 struct pci_dev *pci;
@@ -339,6 +333,10 @@ struct azx {
339 /* Register interaction. */ 333 /* Register interaction. */
340 const struct hda_controller_ops *ops; 334 const struct hda_controller_ops *ops;
341 335
336 /* position adjustment callbacks */
337 azx_get_pos_callback_t get_position[2];
338 azx_get_delay_callback_t get_delay[2];
339
342 /* pci resources */ 340 /* pci resources */
343 unsigned long addr; 341 unsigned long addr;
344 void __iomem *remap_addr; 342 void __iomem *remap_addr;
@@ -374,7 +372,6 @@ struct azx {
374#endif 372#endif
375 373
376 /* flags */ 374 /* flags */
377 int position_fix[2]; /* for both playback/capture streams */
378 const int *bdl_pos_adj; 375 const int *bdl_pos_adj;
379 int poll_count; 376 int poll_count;
380 unsigned int running:1; 377 unsigned int running:1;
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index a366ba9293a8..12920b99d238 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -480,8 +480,6 @@ static int hda_tegra_create(struct snd_card *card,
480 INIT_LIST_HEAD(&chip->pcm_list); 480 INIT_LIST_HEAD(&chip->pcm_list);
481 INIT_LIST_HEAD(&chip->list); 481 INIT_LIST_HEAD(&chip->list);
482 482
483 chip->position_fix[0] = POS_FIX_AUTO;
484 chip->position_fix[1] = POS_FIX_AUTO;
485 chip->codec_probe_mask = -1; 483 chip->codec_probe_mask = -1;
486 484
487 chip->single_cmd = false; 485 chip->single_cmd = false;