|
@@ -555,6 +555,7 @@ enum {
|
|
|
#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
|
|
|
#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
|
|
|
#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */
|
|
|
+#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
|
|
|
|
|
|
/* quirks for ATI SB / AMD Hudson */
|
|
|
#define AZX_DCAPS_PRESET_ATI_SB \
|
|
@@ -2143,6 +2144,27 @@ static unsigned int azx_get_position(struct azx *chip,
|
|
|
|
|
|
if (pos >= azx_dev->bufsize)
|
|
|
pos = 0;
|
|
|
+
|
|
|
+ /* calculate runtime delay from LPIB */
|
|
|
+ if (azx_dev->substream->runtime &&
|
|
|
+ chip->position_fix[stream] == POS_FIX_POSBUF &&
|
|
|
+ (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
|
|
|
+ unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
|
|
|
+ int delay;
|
|
|
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
|
+ delay = pos - lpib_pos;
|
|
|
+ else
|
|
|
+ delay = lpib_pos - pos;
|
|
|
+ if (delay < 0)
|
|
|
+ delay += azx_dev->bufsize;
|
|
|
+ if (delay >= azx_dev->period_bytes) {
|
|
|
+ snd_printdd("delay %d > period_bytes %d\n",
|
|
|
+ delay, azx_dev->period_bytes);
|
|
|
+ delay = 0; /* something is wrong */
|
|
|
+ }
|
|
|
+ azx_dev->substream->runtime->delay =
|
|
|
+ bytes_to_frames(azx_dev->substream->runtime, delay);
|
|
|
+ }
|
|
|
return pos;
|
|
|
}
|
|
|
|
|
@@ -3402,7 +3424,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
|
|
/* CPT */
|
|
|
{ PCI_DEVICE(0x8086, 0x1c20),
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
|
|
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
|
|
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
|
|
|
/* PBG */
|
|
|
{ PCI_DEVICE(0x8086, 0x1d20),
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
|
@@ -3410,26 +3432,26 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
|
|
/* Panther Point */
|
|
|
{ PCI_DEVICE(0x8086, 0x1e20),
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
|
|
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
|
|
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
|
|
|
/* Lynx Point */
|
|
|
{ PCI_DEVICE(0x8086, 0x8c20),
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
|
|
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
|
|
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
|
|
|
/* Lynx Point-LP */
|
|
|
{ PCI_DEVICE(0x8086, 0x9c20),
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
|
|
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
|
|
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
|
|
|
/* Lynx Point-LP */
|
|
|
{ PCI_DEVICE(0x8086, 0x9c21),
|
|
|
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
|
|
|
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
|
|
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
|
|
|
/* Haswell */
|
|
|
{ PCI_DEVICE(0x8086, 0x0c0c),
|
|
|
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
|
|
|
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
|
|
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
|
|
|
{ PCI_DEVICE(0x8086, 0x0d0c),
|
|
|
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
|
|
|
- AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
|
|
|
+ AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
|
|
|
/* SCH */
|
|
|
{ PCI_DEVICE(0x8086, 0x811b),
|
|
|
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
|