diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-05-08 04:34:08 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-05-10 02:53:34 -0400 |
commit | 5ae763b1bc573e7ef5d9a96c71c8b3e3a865ad8c (patch) | |
tree | 1d75f4c02465659a44ceefe2f012b198cf702f04 /sound/pci/hda/hda_intel.c | |
parent | a2d96e778d1b15d2213f3b7737aa86fd8eda44cb (diff) |
ALSA: hda - Add the support for Creative SoundCore3D
The controller is compatible with HD-audio 1.0a with some specific
restrictions.
- The BDLE entries can't be over 4k boundary
- No position-buffer and no MSI
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c19e71a94e1b..a70d7e5443aa 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -497,6 +497,7 @@ enum { | |||
497 | AZX_DRIVER_NVIDIA, | 497 | AZX_DRIVER_NVIDIA, |
498 | AZX_DRIVER_TERA, | 498 | AZX_DRIVER_TERA, |
499 | AZX_DRIVER_CTX, | 499 | AZX_DRIVER_CTX, |
500 | AZX_DRIVER_CTHDA, | ||
500 | AZX_DRIVER_GENERIC, | 501 | AZX_DRIVER_GENERIC, |
501 | AZX_NUM_DRIVERS, /* keep this as last entry */ | 502 | AZX_NUM_DRIVERS, /* keep this as last entry */ |
502 | }; | 503 | }; |
@@ -518,6 +519,7 @@ enum { | |||
518 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | 519 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ |
519 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | 520 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ |
520 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | 521 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ |
522 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ | ||
521 | 523 | ||
522 | /* quirks for ATI SB / AMD Hudson */ | 524 | /* quirks for ATI SB / AMD Hudson */ |
523 | #define AZX_DCAPS_PRESET_ATI_SB \ | 525 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -533,6 +535,9 @@ enum { | |||
533 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ | 535 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ |
534 | AZX_DCAPS_ALIGN_BUFSIZE) | 536 | AZX_DCAPS_ALIGN_BUFSIZE) |
535 | 537 | ||
538 | #define AZX_DCAPS_PRESET_CTHDA \ | ||
539 | (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY) | ||
540 | |||
536 | static char *driver_short_names[] __devinitdata = { | 541 | static char *driver_short_names[] __devinitdata = { |
537 | [AZX_DRIVER_ICH] = "HDA Intel", | 542 | [AZX_DRIVER_ICH] = "HDA Intel", |
538 | [AZX_DRIVER_PCH] = "HDA Intel PCH", | 543 | [AZX_DRIVER_PCH] = "HDA Intel PCH", |
@@ -546,6 +551,7 @@ static char *driver_short_names[] __devinitdata = { | |||
546 | [AZX_DRIVER_NVIDIA] = "HDA NVidia", | 551 | [AZX_DRIVER_NVIDIA] = "HDA NVidia", |
547 | [AZX_DRIVER_TERA] = "HDA Teradici", | 552 | [AZX_DRIVER_TERA] = "HDA Teradici", |
548 | [AZX_DRIVER_CTX] = "HDA Creative", | 553 | [AZX_DRIVER_CTX] = "HDA Creative", |
554 | [AZX_DRIVER_CTHDA] = "HDA Creative", | ||
549 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", | 555 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", |
550 | }; | 556 | }; |
551 | 557 | ||
@@ -1283,7 +1289,8 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1283 | /* | 1289 | /* |
1284 | * set up a BDL entry | 1290 | * set up a BDL entry |
1285 | */ | 1291 | */ |
1286 | static int setup_bdle(struct snd_pcm_substream *substream, | 1292 | static int setup_bdle(struct azx *chip, |
1293 | struct snd_pcm_substream *substream, | ||
1287 | struct azx_dev *azx_dev, u32 **bdlp, | 1294 | struct azx_dev *azx_dev, u32 **bdlp, |
1288 | int ofs, int size, int with_ioc) | 1295 | int ofs, int size, int with_ioc) |
1289 | { | 1296 | { |
@@ -1302,6 +1309,12 @@ static int setup_bdle(struct snd_pcm_substream *substream, | |||
1302 | bdl[1] = cpu_to_le32(upper_32_bits(addr)); | 1309 | bdl[1] = cpu_to_le32(upper_32_bits(addr)); |
1303 | /* program the size field of the BDL entry */ | 1310 | /* program the size field of the BDL entry */ |
1304 | chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); | 1311 | chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); |
1312 | /* one BDLE cannot cross 4K boundary on CTHDA chips */ | ||
1313 | if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) { | ||
1314 | u32 remain = 0x1000 - (ofs & 0xfff); | ||
1315 | if (chunk > remain) | ||
1316 | chunk = remain; | ||
1317 | } | ||
1305 | bdl[2] = cpu_to_le32(chunk); | 1318 | bdl[2] = cpu_to_le32(chunk); |
1306 | /* program the IOC to enable interrupt | 1319 | /* program the IOC to enable interrupt |
1307 | * only when the whole fragment is processed | 1320 | * only when the whole fragment is processed |
@@ -1354,7 +1367,7 @@ static int azx_setup_periods(struct azx *chip, | |||
1354 | bdl_pos_adj[chip->dev_index]); | 1367 | bdl_pos_adj[chip->dev_index]); |
1355 | pos_adj = 0; | 1368 | pos_adj = 0; |
1356 | } else { | 1369 | } else { |
1357 | ofs = setup_bdle(substream, azx_dev, | 1370 | ofs = setup_bdle(chip, substream, azx_dev, |
1358 | &bdl, ofs, pos_adj, | 1371 | &bdl, ofs, pos_adj, |
1359 | !substream->runtime->no_period_wakeup); | 1372 | !substream->runtime->no_period_wakeup); |
1360 | if (ofs < 0) | 1373 | if (ofs < 0) |
@@ -1364,10 +1377,10 @@ static int azx_setup_periods(struct azx *chip, | |||
1364 | pos_adj = 0; | 1377 | pos_adj = 0; |
1365 | for (i = 0; i < periods; i++) { | 1378 | for (i = 0; i < periods; i++) { |
1366 | if (i == periods - 1 && pos_adj) | 1379 | if (i == periods - 1 && pos_adj) |
1367 | ofs = setup_bdle(substream, azx_dev, &bdl, ofs, | 1380 | ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, |
1368 | period_bytes - pos_adj, 0); | 1381 | period_bytes - pos_adj, 0); |
1369 | else | 1382 | else |
1370 | ofs = setup_bdle(substream, azx_dev, &bdl, ofs, | 1383 | ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, |
1371 | period_bytes, | 1384 | period_bytes, |
1372 | !substream->runtime->no_period_wakeup); | 1385 | !substream->runtime->no_period_wakeup); |
1373 | if (ofs < 0) | 1386 | if (ofs < 0) |
@@ -3116,6 +3129,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3116 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | | 3129 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | |
3117 | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, | 3130 | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, |
3118 | #endif | 3131 | #endif |
3132 | /* CTHDA chips */ | ||
3133 | { PCI_DEVICE(0x1102, 0x0010), | ||
3134 | .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, | ||
3135 | { PCI_DEVICE(0x1102, 0x0012), | ||
3136 | .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, | ||
3119 | /* Vortex86MX */ | 3137 | /* Vortex86MX */ |
3120 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, | 3138 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, |
3121 | /* VMware HDAudio */ | 3139 | /* VMware HDAudio */ |