diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 15107df1f490..9590ece2099d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -62,7 +62,7 @@ MODULE_PARM_DESC(enable, "Enable Intel HD audio interface."); | |||
62 | module_param_array(model, charp, NULL, 0444); | 62 | module_param_array(model, charp, NULL, 0444); |
63 | MODULE_PARM_DESC(model, "Use the given board model."); | 63 | MODULE_PARM_DESC(model, "Use the given board model."); |
64 | module_param_array(position_fix, int, NULL, 0444); | 64 | module_param_array(position_fix, int, NULL, 0444); |
65 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF)."); | 65 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); |
66 | 66 | ||
67 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
68 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | 68 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," |
@@ -164,7 +164,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
164 | /* max buffer size - no h/w limit, you can increase as you like */ | 164 | /* max buffer size - no h/w limit, you can increase as you like */ |
165 | #define AZX_MAX_BUF_SIZE (1024*1024*1024) | 165 | #define AZX_MAX_BUF_SIZE (1024*1024*1024) |
166 | /* max number of PCM devics per card */ | 166 | /* max number of PCM devics per card */ |
167 | #define AZX_MAX_PCMS 8 | 167 | #define AZX_MAX_AUDIO_PCMS 6 |
168 | #define AZX_MAX_MODEM_PCMS 2 | ||
169 | #define AZX_MAX_PCMS (AZX_MAX_AUDIO_PCMS + AZX_MAX_MODEM_PCMS) | ||
168 | 170 | ||
169 | /* RIRB int mask: overrun[2], response[0] */ | 171 | /* RIRB int mask: overrun[2], response[0] */ |
170 | #define RIRB_INT_RESPONSE 0x01 | 172 | #define RIRB_INT_RESPONSE 0x01 |
@@ -211,9 +213,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
211 | 213 | ||
212 | /* position fix mode */ | 214 | /* position fix mode */ |
213 | enum { | 215 | enum { |
214 | POS_FIX_FIFO, | 216 | POS_FIX_AUTO, |
215 | POS_FIX_NONE, | 217 | POS_FIX_NONE, |
216 | POS_FIX_POSBUF | 218 | POS_FIX_POSBUF, |
219 | POS_FIX_FIFO, | ||
217 | }; | 220 | }; |
218 | 221 | ||
219 | /* Defines for ATI HD Audio support in SB450 south bridge */ | 222 | /* Defines for ATI HD Audio support in SB450 south bridge */ |
@@ -243,6 +246,7 @@ struct snd_azx_dev { | |||
243 | unsigned int fragsize; /* size of each period in bytes */ | 246 | unsigned int fragsize; /* size of each period in bytes */ |
244 | unsigned int frags; /* number for period in the play buffer */ | 247 | unsigned int frags; /* number for period in the play buffer */ |
245 | unsigned int fifo_size; /* FIFO size */ | 248 | unsigned int fifo_size; /* FIFO size */ |
249 | unsigned int last_pos; /* last updated period position */ | ||
246 | 250 | ||
247 | void __iomem *sd_addr; /* stream descriptor pointer */ | 251 | void __iomem *sd_addr; /* stream descriptor pointer */ |
248 | 252 | ||
@@ -256,6 +260,7 @@ struct snd_azx_dev { | |||
256 | 260 | ||
257 | unsigned int opened: 1; | 261 | unsigned int opened: 1; |
258 | unsigned int running: 1; | 262 | unsigned int running: 1; |
263 | unsigned int period_updating: 1; | ||
259 | }; | 264 | }; |
260 | 265 | ||
261 | /* CORB/RIRB */ | 266 | /* CORB/RIRB */ |
@@ -724,11 +729,9 @@ static void azx_init_chip(azx_t *chip) | |||
724 | /* initialize the codec command I/O */ | 729 | /* initialize the codec command I/O */ |
725 | azx_init_cmd_io(chip); | 730 | azx_init_cmd_io(chip); |
726 | 731 | ||
727 | if (chip->position_fix == POS_FIX_POSBUF) { | 732 | /* program the position buffer */ |
728 | /* program the position buffer */ | 733 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
729 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 734 | azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); |
730 | azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); | ||
731 | } | ||
732 | 735 | ||
733 | /* For ATI SB450 azalia HD audio, we need to enable snoop */ | 736 | /* For ATI SB450 azalia HD audio, we need to enable snoop */ |
734 | if (chip->driver_type == AZX_DRIVER_ATI) { | 737 | if (chip->driver_type == AZX_DRIVER_ATI) { |
@@ -763,9 +766,11 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) | |||
763 | if (status & azx_dev->sd_int_sta_mask) { | 766 | if (status & azx_dev->sd_int_sta_mask) { |
764 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 767 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
765 | if (azx_dev->substream && azx_dev->running) { | 768 | if (azx_dev->substream && azx_dev->running) { |
769 | azx_dev->period_updating = 1; | ||
766 | spin_unlock(&chip->reg_lock); | 770 | spin_unlock(&chip->reg_lock); |
767 | snd_pcm_period_elapsed(azx_dev->substream); | 771 | snd_pcm_period_elapsed(azx_dev->substream); |
768 | spin_lock(&chip->reg_lock); | 772 | spin_lock(&chip->reg_lock); |
773 | azx_dev->period_updating = 0; | ||
769 | } | 774 | } |
770 | } | 775 | } |
771 | } | 776 | } |
@@ -866,11 +871,9 @@ static int azx_setup_controller(azx_t *chip, azx_dev_t *azx_dev) | |||
866 | /* upper BDL address */ | 871 | /* upper BDL address */ |
867 | azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr)); | 872 | azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr)); |
868 | 873 | ||
869 | if (chip->position_fix == POS_FIX_POSBUF) { | 874 | /* enable the position buffer */ |
870 | /* enable the position buffer */ | 875 | if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) |
871 | if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) | 876 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); |
872 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); | ||
873 | } | ||
874 | 877 | ||
875 | /* set the interrupt enable bits in the descriptor control register */ | 878 | /* set the interrupt enable bits in the descriptor control register */ |
876 | azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); | 879 | azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); |
@@ -1078,6 +1081,7 @@ static int azx_pcm_prepare(snd_pcm_substream_t *substream) | |||
1078 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; | 1081 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; |
1079 | else | 1082 | else |
1080 | azx_dev->fifo_size = 0; | 1083 | azx_dev->fifo_size = 0; |
1084 | azx_dev->last_pos = 0; | ||
1081 | 1085 | ||
1082 | return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, | 1086 | return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, |
1083 | azx_dev->format_val, substream); | 1087 | azx_dev->format_val, substream); |
@@ -1133,6 +1137,26 @@ static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream) | |||
1133 | pos = azx_sd_readl(azx_dev, SD_LPIB); | 1137 | pos = azx_sd_readl(azx_dev, SD_LPIB); |
1134 | if (chip->position_fix == POS_FIX_FIFO) | 1138 | if (chip->position_fix == POS_FIX_FIFO) |
1135 | pos += azx_dev->fifo_size; | 1139 | pos += azx_dev->fifo_size; |
1140 | else if (chip->position_fix == POS_FIX_AUTO && azx_dev->period_updating) { | ||
1141 | /* check the validity of DMA position */ | ||
1142 | unsigned int diff = 0; | ||
1143 | azx_dev->last_pos += azx_dev->fragsize; | ||
1144 | if (azx_dev->last_pos > pos) | ||
1145 | diff = azx_dev->last_pos - pos; | ||
1146 | if (azx_dev->last_pos >= azx_dev->bufsize) { | ||
1147 | if (pos < azx_dev->fragsize) | ||
1148 | diff = 0; | ||
1149 | azx_dev->last_pos = 0; | ||
1150 | } | ||
1151 | if (diff > 0 && diff <= azx_dev->fifo_size) | ||
1152 | pos += azx_dev->fifo_size; | ||
1153 | else { | ||
1154 | snd_printdd(KERN_INFO "hda_intel: DMA position fix %d, switching to posbuf\n", diff); | ||
1155 | chip->position_fix = POS_FIX_POSBUF; | ||
1156 | pos = *azx_dev->posbuf; | ||
1157 | } | ||
1158 | azx_dev->period_updating = 0; | ||
1159 | } | ||
1136 | } | 1160 | } |
1137 | if (pos >= azx_dev->bufsize) | 1161 | if (pos >= azx_dev->bufsize) |
1138 | pos = 0; | 1162 | pos = 0; |
@@ -1203,12 +1227,33 @@ static int __devinit azx_pcm_create(azx_t *chip) | |||
1203 | if ((err = snd_hda_build_pcms(chip->bus)) < 0) | 1227 | if ((err = snd_hda_build_pcms(chip->bus)) < 0) |
1204 | return err; | 1228 | return err; |
1205 | 1229 | ||
1230 | /* create audio PCMs */ | ||
1206 | pcm_dev = 0; | 1231 | pcm_dev = 0; |
1207 | list_for_each(p, &chip->bus->codec_list) { | 1232 | list_for_each(p, &chip->bus->codec_list) { |
1208 | codec = list_entry(p, struct hda_codec, list); | 1233 | codec = list_entry(p, struct hda_codec, list); |
1209 | for (c = 0; c < codec->num_pcms; c++) { | 1234 | for (c = 0; c < codec->num_pcms; c++) { |
1235 | if (codec->pcm_info[c].is_modem) | ||
1236 | continue; /* create later */ | ||
1237 | if (pcm_dev >= AZX_MAX_AUDIO_PCMS) { | ||
1238 | snd_printk(KERN_ERR SFX "Too many audio PCMs\n"); | ||
1239 | return -EINVAL; | ||
1240 | } | ||
1241 | err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); | ||
1242 | if (err < 0) | ||
1243 | return err; | ||
1244 | pcm_dev++; | ||
1245 | } | ||
1246 | } | ||
1247 | |||
1248 | /* create modem PCMs */ | ||
1249 | pcm_dev = AZX_MAX_AUDIO_PCMS; | ||
1250 | list_for_each(p, &chip->bus->codec_list) { | ||
1251 | codec = list_entry(p, struct hda_codec, list); | ||
1252 | for (c = 0; c < codec->num_pcms; c++) { | ||
1253 | if (! codec->pcm_info[c].is_modem) | ||
1254 | continue; /* already created */ | ||
1210 | if (pcm_dev >= AZX_MAX_PCMS) { | 1255 | if (pcm_dev >= AZX_MAX_PCMS) { |
1211 | snd_printk(KERN_ERR SFX "Too many PCMs\n"); | 1256 | snd_printk(KERN_ERR SFX "Too many modem PCMs\n"); |
1212 | return -EINVAL; | 1257 | return -EINVAL; |
1213 | } | 1258 | } |
1214 | err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); | 1259 | err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); |
@@ -1244,8 +1289,7 @@ static int __devinit azx_init_stream(azx_t *chip) | |||
1244 | azx_dev_t *azx_dev = &chip->azx_dev[i]; | 1289 | azx_dev_t *azx_dev = &chip->azx_dev[i]; |
1245 | azx_dev->bdl = (u32 *)(chip->bdl.area + off); | 1290 | azx_dev->bdl = (u32 *)(chip->bdl.area + off); |
1246 | azx_dev->bdl_addr = chip->bdl.addr + off; | 1291 | azx_dev->bdl_addr = chip->bdl.addr + off; |
1247 | if (chip->position_fix == POS_FIX_POSBUF) | 1292 | azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8); |
1248 | azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8); | ||
1249 | /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ | 1293 | /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ |
1250 | azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); | 1294 | azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); |
1251 | /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ | 1295 | /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ |
@@ -1358,7 +1402,7 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, | |||
1358 | if ((err = pci_enable_device(pci)) < 0) | 1402 | if ((err = pci_enable_device(pci)) < 0) |
1359 | return err; | 1403 | return err; |
1360 | 1404 | ||
1361 | chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); | 1405 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
1362 | 1406 | ||
1363 | if (NULL == chip) { | 1407 | if (NULL == chip) { |
1364 | snd_printk(KERN_ERR SFX "cannot allocate chip\n"); | 1408 | snd_printk(KERN_ERR SFX "cannot allocate chip\n"); |
@@ -1437,13 +1481,11 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, | |||
1437 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); | 1481 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); |
1438 | goto errout; | 1482 | goto errout; |
1439 | } | 1483 | } |
1440 | if (chip->position_fix == POS_FIX_POSBUF) { | 1484 | /* allocate memory for the position buffer */ |
1441 | /* allocate memory for the position buffer */ | 1485 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), |
1442 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | 1486 | chip->num_streams * 8, &chip->posbuf)) < 0) { |
1443 | chip->num_streams * 8, &chip->posbuf)) < 0) { | 1487 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); |
1444 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); | 1488 | goto errout; |
1445 | goto errout; | ||
1446 | } | ||
1447 | } | 1489 | } |
1448 | /* allocate CORB/RIRB */ | 1490 | /* allocate CORB/RIRB */ |
1449 | if ((err = azx_alloc_cmd_io(chip)) < 0) | 1491 | if ((err = azx_alloc_cmd_io(chip)) < 0) |
@@ -1561,6 +1603,7 @@ MODULE_DEVICE_TABLE(pci, azx_ids); | |||
1561 | /* pci_driver definition */ | 1603 | /* pci_driver definition */ |
1562 | static struct pci_driver driver = { | 1604 | static struct pci_driver driver = { |
1563 | .name = "HDA Intel", | 1605 | .name = "HDA Intel", |
1606 | .owner = THIS_MODULE, | ||
1564 | .id_table = azx_ids, | 1607 | .id_table = azx_ids, |
1565 | .probe = azx_probe, | 1608 | .probe = azx_probe, |
1566 | .remove = __devexit_p(azx_remove), | 1609 | .remove = __devexit_p(azx_remove), |