diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 122 |
1 files changed, 76 insertions, 46 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fd12b6991fe4..c096606970ff 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
46 | #include <linux/mutex.h> | ||
46 | #include <sound/core.h> | 47 | #include <sound/core.h> |
47 | #include <sound/initval.h> | 48 | #include <sound/initval.h> |
48 | #include "hda_codec.h" | 49 | #include "hda_codec.h" |
@@ -53,6 +54,7 @@ static char *id = SNDRV_DEFAULT_STR1; | |||
53 | static char *model; | 54 | static char *model; |
54 | static int position_fix; | 55 | static int position_fix; |
55 | static int probe_mask = -1; | 56 | static int probe_mask = -1; |
57 | static int single_cmd; | ||
56 | 58 | ||
57 | module_param(index, int, 0444); | 59 | module_param(index, int, 0444); |
58 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 60 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
@@ -64,6 +66,8 @@ module_param(position_fix, int, 0444); | |||
64 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); | 66 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); |
65 | module_param(probe_mask, int, 0444); | 67 | module_param(probe_mask, int, 0444); |
66 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); | 68 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); |
69 | module_param(single_cmd, bool, 0444); | ||
70 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); | ||
67 | 71 | ||
68 | 72 | ||
69 | /* just for backward compatibility */ | 73 | /* just for backward compatibility */ |
@@ -235,12 +239,6 @@ enum { | |||
235 | #define NVIDIA_HDA_ENABLE_COHBITS 0x0f | 239 | #define NVIDIA_HDA_ENABLE_COHBITS 0x0f |
236 | 240 | ||
237 | /* | 241 | /* |
238 | * Use CORB/RIRB for communication from/to codecs. | ||
239 | * This is the way recommended by Intel (see below). | ||
240 | */ | ||
241 | #define USE_CORB_RIRB | ||
242 | |||
243 | /* | ||
244 | */ | 242 | */ |
245 | 243 | ||
246 | struct azx_dev { | 244 | struct azx_dev { |
@@ -252,7 +250,6 @@ struct azx_dev { | |||
252 | unsigned int fragsize; /* size of each period in bytes */ | 250 | unsigned int fragsize; /* size of each period in bytes */ |
253 | unsigned int frags; /* number for period in the play buffer */ | 251 | unsigned int frags; /* number for period in the play buffer */ |
254 | unsigned int fifo_size; /* FIFO size */ | 252 | unsigned int fifo_size; /* FIFO size */ |
255 | unsigned int last_pos; /* last updated period position */ | ||
256 | 253 | ||
257 | void __iomem *sd_addr; /* stream descriptor pointer */ | 254 | void __iomem *sd_addr; /* stream descriptor pointer */ |
258 | 255 | ||
@@ -263,10 +260,11 @@ struct azx_dev { | |||
263 | unsigned int format_val; /* format value to be set in the controller and the codec */ | 260 | unsigned int format_val; /* format value to be set in the controller and the codec */ |
264 | unsigned char stream_tag; /* assigned stream */ | 261 | unsigned char stream_tag; /* assigned stream */ |
265 | unsigned char index; /* stream index */ | 262 | unsigned char index; /* stream index */ |
263 | /* for sanity check of position buffer */ | ||
264 | unsigned int period_intr; | ||
266 | 265 | ||
267 | unsigned int opened: 1; | 266 | unsigned int opened: 1; |
268 | unsigned int running: 1; | 267 | unsigned int running: 1; |
269 | unsigned int period_updating: 1; | ||
270 | }; | 268 | }; |
271 | 269 | ||
272 | /* CORB/RIRB */ | 270 | /* CORB/RIRB */ |
@@ -300,7 +298,7 @@ struct azx { | |||
300 | 298 | ||
301 | /* locks */ | 299 | /* locks */ |
302 | spinlock_t reg_lock; | 300 | spinlock_t reg_lock; |
303 | struct semaphore open_mutex; | 301 | struct mutex open_mutex; |
304 | 302 | ||
305 | /* streams (x num_streams) */ | 303 | /* streams (x num_streams) */ |
306 | struct azx_dev *azx_dev; | 304 | struct azx_dev *azx_dev; |
@@ -325,6 +323,7 @@ struct azx { | |||
325 | /* flags */ | 323 | /* flags */ |
326 | int position_fix; | 324 | int position_fix; |
327 | unsigned int initialized: 1; | 325 | unsigned int initialized: 1; |
326 | unsigned int single_cmd: 1; | ||
328 | }; | 327 | }; |
329 | 328 | ||
330 | /* driver types */ | 329 | /* driver types */ |
@@ -388,7 +387,6 @@ static char *driver_short_names[] __devinitdata = { | |||
388 | * Interface for HD codec | 387 | * Interface for HD codec |
389 | */ | 388 | */ |
390 | 389 | ||
391 | #ifdef USE_CORB_RIRB | ||
392 | /* | 390 | /* |
393 | * CORB / RIRB interface | 391 | * CORB / RIRB interface |
394 | */ | 392 | */ |
@@ -436,11 +434,7 @@ static void azx_init_cmd_io(struct azx *chip) | |||
436 | /* set N=1, get RIRB response interrupt for new entry */ | 434 | /* set N=1, get RIRB response interrupt for new entry */ |
437 | azx_writew(chip, RINTCNT, 1); | 435 | azx_writew(chip, RINTCNT, 1); |
438 | /* enable rirb dma and response irq */ | 436 | /* enable rirb dma and response irq */ |
439 | #ifdef USE_CORB_RIRB | ||
440 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); | 437 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); |
441 | #else | ||
442 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN); | ||
443 | #endif | ||
444 | chip->rirb.rp = chip->rirb.cmds = 0; | 438 | chip->rirb.rp = chip->rirb.cmds = 0; |
445 | } | 439 | } |
446 | 440 | ||
@@ -452,8 +446,8 @@ static void azx_free_cmd_io(struct azx *chip) | |||
452 | } | 446 | } |
453 | 447 | ||
454 | /* send a command */ | 448 | /* send a command */ |
455 | static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | 449 | static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, |
456 | unsigned int verb, unsigned int para) | 450 | unsigned int verb, unsigned int para) |
457 | { | 451 | { |
458 | struct azx *chip = codec->bus->private_data; | 452 | struct azx *chip = codec->bus->private_data; |
459 | unsigned int wp; | 453 | unsigned int wp; |
@@ -509,18 +503,21 @@ static void azx_update_rirb(struct azx *chip) | |||
509 | } | 503 | } |
510 | 504 | ||
511 | /* receive a response */ | 505 | /* receive a response */ |
512 | static unsigned int azx_get_response(struct hda_codec *codec) | 506 | static unsigned int azx_rirb_get_response(struct hda_codec *codec) |
513 | { | 507 | { |
514 | struct azx *chip = codec->bus->private_data; | 508 | struct azx *chip = codec->bus->private_data; |
515 | int timeout = 50; | 509 | int timeout = 50; |
516 | 510 | ||
517 | while (chip->rirb.cmds) { | 511 | while (chip->rirb.cmds) { |
518 | if (! --timeout) { | 512 | if (! --timeout) { |
519 | if (printk_ratelimit()) | 513 | snd_printk(KERN_ERR |
520 | snd_printk(KERN_ERR | 514 | "hda_intel: azx_get_response timeout, " |
521 | "azx_get_response timeout\n"); | 515 | "switching to single_cmd mode...\n"); |
522 | chip->rirb.rp = azx_readb(chip, RIRBWP); | 516 | chip->rirb.rp = azx_readb(chip, RIRBWP); |
523 | chip->rirb.cmds = 0; | 517 | chip->rirb.cmds = 0; |
518 | /* switch to single_cmd mode */ | ||
519 | chip->single_cmd = 1; | ||
520 | azx_free_cmd_io(chip); | ||
524 | return -1; | 521 | return -1; |
525 | } | 522 | } |
526 | msleep(1); | 523 | msleep(1); |
@@ -528,7 +525,6 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
528 | return chip->rirb.res; /* the last value */ | 525 | return chip->rirb.res; /* the last value */ |
529 | } | 526 | } |
530 | 527 | ||
531 | #else | ||
532 | /* | 528 | /* |
533 | * Use the single immediate command instead of CORB/RIRB for simplicity | 529 | * Use the single immediate command instead of CORB/RIRB for simplicity |
534 | * | 530 | * |
@@ -539,13 +535,10 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
539 | * I left the codes, however, for debugging/testing purposes. | 535 | * I left the codes, however, for debugging/testing purposes. |
540 | */ | 536 | */ |
541 | 537 | ||
542 | #define azx_alloc_cmd_io(chip) 0 | ||
543 | #define azx_init_cmd_io(chip) | ||
544 | #define azx_free_cmd_io(chip) | ||
545 | |||
546 | /* send a command */ | 538 | /* send a command */ |
547 | static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | 539 | static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, |
548 | unsigned int verb, unsigned int para) | 540 | int direct, unsigned int verb, |
541 | unsigned int para) | ||
549 | { | 542 | { |
550 | struct azx *chip = codec->bus->private_data; | 543 | struct azx *chip = codec->bus->private_data; |
551 | u32 val; | 544 | u32 val; |
@@ -573,7 +566,7 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
573 | } | 566 | } |
574 | 567 | ||
575 | /* receive a response */ | 568 | /* receive a response */ |
576 | static unsigned int azx_get_response(struct hda_codec *codec) | 569 | static unsigned int azx_single_get_response(struct hda_codec *codec) |
577 | { | 570 | { |
578 | struct azx *chip = codec->bus->private_data; | 571 | struct azx *chip = codec->bus->private_data; |
579 | int timeout = 50; | 572 | int timeout = 50; |
@@ -588,9 +581,35 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
588 | return (unsigned int)-1; | 581 | return (unsigned int)-1; |
589 | } | 582 | } |
590 | 583 | ||
591 | #define azx_update_rirb(chip) | 584 | /* |
585 | * The below are the main callbacks from hda_codec. | ||
586 | * | ||
587 | * They are just the skeleton to call sub-callbacks according to the | ||
588 | * current setting of chip->single_cmd. | ||
589 | */ | ||
590 | |||
591 | /* send a command */ | ||
592 | static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, | ||
593 | int direct, unsigned int verb, | ||
594 | unsigned int para) | ||
595 | { | ||
596 | struct azx *chip = codec->bus->private_data; | ||
597 | if (chip->single_cmd) | ||
598 | return azx_single_send_cmd(codec, nid, direct, verb, para); | ||
599 | else | ||
600 | return azx_corb_send_cmd(codec, nid, direct, verb, para); | ||
601 | } | ||
602 | |||
603 | /* get a response */ | ||
604 | static unsigned int azx_get_response(struct hda_codec *codec) | ||
605 | { | ||
606 | struct azx *chip = codec->bus->private_data; | ||
607 | if (chip->single_cmd) | ||
608 | return azx_single_get_response(codec); | ||
609 | else | ||
610 | return azx_rirb_get_response(codec); | ||
611 | } | ||
592 | 612 | ||
593 | #endif /* USE_CORB_RIRB */ | ||
594 | 613 | ||
595 | /* reset codec link */ | 614 | /* reset codec link */ |
596 | static int azx_reset(struct azx *chip) | 615 | static int azx_reset(struct azx *chip) |
@@ -737,7 +756,8 @@ static void azx_init_chip(struct azx *chip) | |||
737 | azx_int_enable(chip); | 756 | azx_int_enable(chip); |
738 | 757 | ||
739 | /* initialize the codec command I/O */ | 758 | /* initialize the codec command I/O */ |
740 | azx_init_cmd_io(chip); | 759 | if (! chip->single_cmd) |
760 | azx_init_cmd_io(chip); | ||
741 | 761 | ||
742 | /* program the position buffer */ | 762 | /* program the position buffer */ |
743 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 763 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
@@ -784,11 +804,10 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) | |||
784 | if (status & azx_dev->sd_int_sta_mask) { | 804 | if (status & azx_dev->sd_int_sta_mask) { |
785 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 805 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
786 | if (azx_dev->substream && azx_dev->running) { | 806 | if (azx_dev->substream && azx_dev->running) { |
787 | azx_dev->period_updating = 1; | 807 | azx_dev->period_intr++; |
788 | spin_unlock(&chip->reg_lock); | 808 | spin_unlock(&chip->reg_lock); |
789 | snd_pcm_period_elapsed(azx_dev->substream); | 809 | snd_pcm_period_elapsed(azx_dev->substream); |
790 | spin_lock(&chip->reg_lock); | 810 | spin_lock(&chip->reg_lock); |
791 | azx_dev->period_updating = 0; | ||
792 | } | 811 | } |
793 | } | 812 | } |
794 | } | 813 | } |
@@ -796,7 +815,7 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) | |||
796 | /* clear rirb int */ | 815 | /* clear rirb int */ |
797 | status = azx_readb(chip, RIRBSTS); | 816 | status = azx_readb(chip, RIRBSTS); |
798 | if (status & RIRB_INT_MASK) { | 817 | if (status & RIRB_INT_MASK) { |
799 | if (status & RIRB_INT_RESPONSE) | 818 | if (! chip->single_cmd && (status & RIRB_INT_RESPONSE)) |
800 | azx_update_rirb(chip); | 819 | azx_update_rirb(chip); |
801 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); | 820 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); |
802 | } | 821 | } |
@@ -1002,10 +1021,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1002 | unsigned long flags; | 1021 | unsigned long flags; |
1003 | int err; | 1022 | int err; |
1004 | 1023 | ||
1005 | down(&chip->open_mutex); | 1024 | mutex_lock(&chip->open_mutex); |
1006 | azx_dev = azx_assign_device(chip, substream->stream); | 1025 | azx_dev = azx_assign_device(chip, substream->stream); |
1007 | if (azx_dev == NULL) { | 1026 | if (azx_dev == NULL) { |
1008 | up(&chip->open_mutex); | 1027 | mutex_unlock(&chip->open_mutex); |
1009 | return -EBUSY; | 1028 | return -EBUSY; |
1010 | } | 1029 | } |
1011 | runtime->hw = azx_pcm_hw; | 1030 | runtime->hw = azx_pcm_hw; |
@@ -1017,7 +1036,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1017 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 1036 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
1018 | if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { | 1037 | if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { |
1019 | azx_release_device(azx_dev); | 1038 | azx_release_device(azx_dev); |
1020 | up(&chip->open_mutex); | 1039 | mutex_unlock(&chip->open_mutex); |
1021 | return err; | 1040 | return err; |
1022 | } | 1041 | } |
1023 | spin_lock_irqsave(&chip->reg_lock, flags); | 1042 | spin_lock_irqsave(&chip->reg_lock, flags); |
@@ -1026,7 +1045,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1026 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1045 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1027 | 1046 | ||
1028 | runtime->private_data = azx_dev; | 1047 | runtime->private_data = azx_dev; |
1029 | up(&chip->open_mutex); | 1048 | mutex_unlock(&chip->open_mutex); |
1030 | return 0; | 1049 | return 0; |
1031 | } | 1050 | } |
1032 | 1051 | ||
@@ -1038,14 +1057,14 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) | |||
1038 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1057 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1039 | unsigned long flags; | 1058 | unsigned long flags; |
1040 | 1059 | ||
1041 | down(&chip->open_mutex); | 1060 | mutex_lock(&chip->open_mutex); |
1042 | spin_lock_irqsave(&chip->reg_lock, flags); | 1061 | spin_lock_irqsave(&chip->reg_lock, flags); |
1043 | azx_dev->substream = NULL; | 1062 | azx_dev->substream = NULL; |
1044 | azx_dev->running = 0; | 1063 | azx_dev->running = 0; |
1045 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1064 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1046 | azx_release_device(azx_dev); | 1065 | azx_release_device(azx_dev); |
1047 | hinfo->ops.close(hinfo, apcm->codec, substream); | 1066 | hinfo->ops.close(hinfo, apcm->codec, substream); |
1048 | up(&chip->open_mutex); | 1067 | mutex_unlock(&chip->open_mutex); |
1049 | return 0; | 1068 | return 0; |
1050 | } | 1069 | } |
1051 | 1070 | ||
@@ -1099,7 +1118,6 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1099 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; | 1118 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; |
1100 | else | 1119 | else |
1101 | azx_dev->fifo_size = 0; | 1120 | azx_dev->fifo_size = 0; |
1102 | azx_dev->last_pos = 0; | ||
1103 | 1121 | ||
1104 | return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, | 1122 | return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, |
1105 | azx_dev->format_val, substream); | 1123 | azx_dev->format_val, substream); |
@@ -1147,10 +1165,20 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) | |||
1147 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1165 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1148 | unsigned int pos; | 1166 | unsigned int pos; |
1149 | 1167 | ||
1150 | if (chip->position_fix == POS_FIX_POSBUF) { | 1168 | if (chip->position_fix == POS_FIX_POSBUF || |
1169 | chip->position_fix == POS_FIX_AUTO) { | ||
1151 | /* use the position buffer */ | 1170 | /* use the position buffer */ |
1152 | pos = *azx_dev->posbuf; | 1171 | pos = *azx_dev->posbuf; |
1172 | if (chip->position_fix == POS_FIX_AUTO && | ||
1173 | azx_dev->period_intr == 1 && ! pos) { | ||
1174 | printk(KERN_WARNING | ||
1175 | "hda-intel: Invalid position buffer, " | ||
1176 | "using LPIB read method instead.\n"); | ||
1177 | chip->position_fix = POS_FIX_NONE; | ||
1178 | goto read_lpib; | ||
1179 | } | ||
1153 | } else { | 1180 | } else { |
1181 | read_lpib: | ||
1154 | /* read LPIB */ | 1182 | /* read LPIB */ |
1155 | pos = azx_sd_readl(azx_dev, SD_LPIB); | 1183 | pos = azx_sd_readl(azx_dev, SD_LPIB); |
1156 | if (chip->position_fix == POS_FIX_FIFO) | 1184 | if (chip->position_fix == POS_FIX_FIFO) |
@@ -1415,13 +1443,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1415 | } | 1443 | } |
1416 | 1444 | ||
1417 | spin_lock_init(&chip->reg_lock); | 1445 | spin_lock_init(&chip->reg_lock); |
1418 | init_MUTEX(&chip->open_mutex); | 1446 | mutex_init(&chip->open_mutex); |
1419 | chip->card = card; | 1447 | chip->card = card; |
1420 | chip->pci = pci; | 1448 | chip->pci = pci; |
1421 | chip->irq = -1; | 1449 | chip->irq = -1; |
1422 | chip->driver_type = driver_type; | 1450 | chip->driver_type = driver_type; |
1423 | 1451 | ||
1424 | chip->position_fix = position_fix ? position_fix : POS_FIX_POSBUF; | 1452 | chip->position_fix = position_fix; |
1453 | chip->single_cmd = single_cmd; | ||
1425 | 1454 | ||
1426 | #if BITS_PER_LONG != 64 | 1455 | #if BITS_PER_LONG != 64 |
1427 | /* Fix up base address on ULI M5461 */ | 1456 | /* Fix up base address on ULI M5461 */ |
@@ -1492,8 +1521,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1492 | goto errout; | 1521 | goto errout; |
1493 | } | 1522 | } |
1494 | /* allocate CORB/RIRB */ | 1523 | /* allocate CORB/RIRB */ |
1495 | if ((err = azx_alloc_cmd_io(chip)) < 0) | 1524 | if (! chip->single_cmd) |
1496 | goto errout; | 1525 | if ((err = azx_alloc_cmd_io(chip)) < 0) |
1526 | goto errout; | ||
1497 | 1527 | ||
1498 | /* initialize streams */ | 1528 | /* initialize streams */ |
1499 | azx_init_stream(chip); | 1529 | azx_init_stream(chip); |