aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-05-12 08:26:27 -0400
committerJaroslav Kysela <perex@suse.cz>2005-05-29 04:08:30 -0400
commitc74db86bcf0897cdd4dc1f85ae0d76ef59aaeb20 (patch)
tree07ca89ae966291074bdf5eea73aaaed14edb89dd /sound/pci/hda/hda_intel.c
parent091bf4dcab10b083f944d4eafbe0c734786485fe (diff)
[ALSA] Add position_fix module option
Documentation,HDA Intel driver Added position_fix module option to HDA-intel driver for fixing up the DMA position (possibly hardware-) bugs. 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.c85
1 files changed, 48 insertions, 37 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index cbc9ca73c2ab..104593fa08eb 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -51,6 +51,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
51static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 51static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
53static char *model[SNDRV_CARDS]; 53static char *model[SNDRV_CARDS];
54static int position_fix[SNDRV_CARDS];
54 55
55module_param_array(index, int, NULL, 0444); 56module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); 57MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -60,6 +61,8 @@ module_param_array(enable, bool, NULL, 0444);
60MODULE_PARM_DESC(enable, "Enable Intel HD audio interface."); 61MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
61module_param_array(model, charp, NULL, 0444); 62module_param_array(model, charp, NULL, 0444);
62MODULE_PARM_DESC(model, "Use the given board model."); 63MODULE_PARM_DESC(model, "Use the given board model.");
64module_param_array(position_fix, bool, NULL, 0444);
65MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF).");
63 66
64MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
65MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," 68MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
@@ -183,6 +186,12 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
183#define ICH6_MAX_CORB_ENTRIES 256 186#define ICH6_MAX_CORB_ENTRIES 256
184#define ICH6_MAX_RIRB_ENTRIES 256 187#define ICH6_MAX_RIRB_ENTRIES 256
185 188
189/* position fix mode */
190enum {
191 POS_FIX_FIFO,
192 POS_FIX_NONE,
193 POS_FIX_POSBUF
194};
186 195
187/* 196/*
188 * Use CORB/RIRB for communication from/to codecs. 197 * Use CORB/RIRB for communication from/to codecs.
@@ -191,12 +200,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
191#define USE_CORB_RIRB 200#define USE_CORB_RIRB
192 201
193/* 202/*
194 * Define this if use the position buffer instead of reading SD_LPIB
195 * It's not used as default since SD_LPIB seems to give more accurate position
196 */
197/* #define USE_POSBUF */
198
199/*
200 */ 203 */
201 204
202typedef struct snd_azx azx_t; 205typedef struct snd_azx azx_t;
@@ -271,6 +274,9 @@ struct snd_azx {
271 struct snd_dma_buffer bdl; 274 struct snd_dma_buffer bdl;
272 struct snd_dma_buffer rb; 275 struct snd_dma_buffer rb;
273 struct snd_dma_buffer posbuf; 276 struct snd_dma_buffer posbuf;
277
278 /* flags */
279 int position_fix;
274}; 280};
275 281
276/* 282/*
@@ -657,11 +663,11 @@ static void azx_init_chip(azx_t *chip)
657 /* initialize the codec command I/O */ 663 /* initialize the codec command I/O */
658 azx_init_cmd_io(chip); 664 azx_init_cmd_io(chip);
659 665
660#ifdef USE_POSBUF 666 if (chip->position_fix == POS_FIX_POSBUF) {
661 /* program the position buffer */ 667 /* program the position buffer */
662 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); 668 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
663 azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); 669 azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
664#endif 670 }
665} 671}
666 672
667 673
@@ -791,11 +797,12 @@ static int azx_setup_controller(azx_t *chip, azx_dev_t *azx_dev)
791 /* upper BDL address */ 797 /* upper BDL address */
792 azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr)); 798 azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr));
793 799
794#ifdef USE_POSBUF 800 if (chip->position_fix == POS_FIX_POSBUF) {
795 /* enable the position buffer */ 801 /* enable the position buffer */
796 if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 802 if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
797 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); 803 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
798#endif 804 }
805
799 /* set the interrupt enable bits in the descriptor control register */ 806 /* set the interrupt enable bits in the descriptor control register */
800 azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); 807 azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
801 808
@@ -1036,16 +1043,20 @@ static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
1036 1043
1037static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream) 1044static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream)
1038{ 1045{
1046 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1047 azx_t *chip = apcm->chip;
1039 azx_dev_t *azx_dev = get_azx_dev(substream); 1048 azx_dev_t *azx_dev = get_azx_dev(substream);
1040 unsigned int pos; 1049 unsigned int pos;
1041 1050
1042#ifdef USE_POSBUF 1051 if (chip->position_fix == POS_FIX_POSBUF) {
1043 /* use the position buffer */ 1052 /* use the position buffer */
1044 pos = *azx_dev->posbuf; 1053 pos = *azx_dev->posbuf;
1045#else 1054 } else {
1046 /* read LPIB */ 1055 /* read LPIB */
1047 pos = azx_sd_readl(azx_dev, SD_LPIB) + azx_dev->fifo_size; 1056 pos = azx_sd_readl(azx_dev, SD_LPIB);
1048#endif 1057 if (chip->position_fix == POS_FIX_FIFO)
1058 pos += azx_dev->fifo_size;
1059 }
1049 if (pos >= azx_dev->bufsize) 1060 if (pos >= azx_dev->bufsize)
1050 pos = 0; 1061 pos = 0;
1051 return bytes_to_frames(substream->runtime, pos); 1062 return bytes_to_frames(substream->runtime, pos);
@@ -1155,9 +1166,8 @@ static int __devinit azx_init_stream(azx_t *chip)
1155 azx_dev_t *azx_dev = &chip->azx_dev[i]; 1166 azx_dev_t *azx_dev = &chip->azx_dev[i];
1156 azx_dev->bdl = (u32 *)(chip->bdl.area + off); 1167 azx_dev->bdl = (u32 *)(chip->bdl.area + off);
1157 azx_dev->bdl_addr = chip->bdl.addr + off; 1168 azx_dev->bdl_addr = chip->bdl.addr + off;
1158#ifdef USE_POSBUF 1169 if (chip->position_fix == POS_FIX_POSBUF)
1159 azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8); 1170 azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
1160#endif
1161 /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ 1171 /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
1162 azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); 1172 azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
1163 /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ 1173 /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
@@ -1237,10 +1247,8 @@ static int azx_free(azx_t *chip)
1237 snd_dma_free_pages(&chip->bdl); 1247 snd_dma_free_pages(&chip->bdl);
1238 if (chip->rb.area) 1248 if (chip->rb.area)
1239 snd_dma_free_pages(&chip->rb); 1249 snd_dma_free_pages(&chip->rb);
1240#ifdef USE_POSBUF
1241 if (chip->posbuf.area) 1250 if (chip->posbuf.area)
1242 snd_dma_free_pages(&chip->posbuf); 1251 snd_dma_free_pages(&chip->posbuf);
1243#endif
1244 pci_release_regions(chip->pci); 1252 pci_release_regions(chip->pci);
1245 pci_disable_device(chip->pci); 1253 pci_disable_device(chip->pci);
1246 kfree(chip); 1254 kfree(chip);
@@ -1256,7 +1264,8 @@ static int azx_dev_free(snd_device_t *device)
1256/* 1264/*
1257 * constructor 1265 * constructor
1258 */ 1266 */
1259static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, azx_t **rchip) 1267static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
1268 int posfix, azx_t **rchip)
1260{ 1269{
1261 azx_t *chip; 1270 azx_t *chip;
1262 int err = 0; 1271 int err = 0;
@@ -1283,6 +1292,8 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, azx_t **r
1283 chip->pci = pci; 1292 chip->pci = pci;
1284 chip->irq = -1; 1293 chip->irq = -1;
1285 1294
1295 chip->position_fix = posfix;
1296
1286 if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) { 1297 if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) {
1287 kfree(chip); 1298 kfree(chip);
1288 pci_disable_device(pci); 1299 pci_disable_device(pci);
@@ -1314,14 +1325,14 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, azx_t **r
1314 snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); 1325 snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
1315 goto errout; 1326 goto errout;
1316 } 1327 }
1317#ifdef USE_POSBUF 1328 if (chip->position_fix == POS_FIX_POSBUF) {
1318 /* allocate memory for the position buffer */ 1329 /* allocate memory for the position buffer */
1319 if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 1330 if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
1320 MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) { 1331 MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) {
1321 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); 1332 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
1322 goto errout; 1333 goto errout;
1334 }
1323 } 1335 }
1324#endif
1325 /* allocate CORB/RIRB */ 1336 /* allocate CORB/RIRB */
1326 if ((err = azx_alloc_cmd_io(chip)) < 0) 1337 if ((err = azx_alloc_cmd_io(chip)) < 0)
1327 goto errout; 1338 goto errout;
@@ -1372,7 +1383,7 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *
1372 return -ENOMEM; 1383 return -ENOMEM;
1373 } 1384 }
1374 1385
1375 if ((err = azx_create(card, pci, &chip)) < 0) { 1386 if ((err = azx_create(card, pci, position_fix[dev], &chip)) < 0) {
1376 snd_card_free(card); 1387 snd_card_free(card);
1377 return err; 1388 return err;
1378 } 1389 }