aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 0ff8b9b9629e..ddae3c479a88 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -55,10 +55,10 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
55static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 55static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
56static char *model[SNDRV_CARDS]; 56static char *model[SNDRV_CARDS];
57static int position_fix[SNDRV_CARDS]; 57static int position_fix[SNDRV_CARDS];
58static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
58static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 59static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
59static int single_cmd; 60static int single_cmd;
60static int enable_msi; 61static int enable_msi;
61static int bdl_pos_adj = 1;
62 62
63module_param_array(index, int, NULL, 0444); 63module_param_array(index, int, NULL, 0444);
64MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); 64MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -71,6 +71,8 @@ MODULE_PARM_DESC(model, "Use the given board model.");
71module_param_array(position_fix, int, NULL, 0444); 71module_param_array(position_fix, int, NULL, 0444);
72MODULE_PARM_DESC(position_fix, "Fix DMA pointer " 72MODULE_PARM_DESC(position_fix, "Fix DMA pointer "
73 "(0 = auto, 1 = none, 2 = POSBUF)."); 73 "(0 = auto, 1 = none, 2 = POSBUF).");
74module_param_array(bdl_pos_adj, int, NULL, 0644);
75MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
74module_param_array(probe_mask, int, NULL, 0444); 76module_param_array(probe_mask, int, NULL, 0444);
75MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); 77MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
76module_param(single_cmd, bool, 0444); 78module_param(single_cmd, bool, 0444);
@@ -78,8 +80,6 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
78 "(for debugging only)."); 80 "(for debugging only).");
79module_param(enable_msi, int, 0444); 81module_param(enable_msi, int, 0444);
80MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 82MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
81module_param(bdl_pos_adj, int, 0644);
82MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset");
83 83
84#ifdef CONFIG_SND_HDA_POWER_SAVE 84#ifdef CONFIG_SND_HDA_POWER_SAVE
85/* power_save option is defined in hda_codec.c */ 85/* power_save option is defined in hda_codec.c */
@@ -330,6 +330,7 @@ struct azx_rb {
330struct azx { 330struct azx {
331 struct snd_card *card; 331 struct snd_card *card;
332 struct pci_dev *pci; 332 struct pci_dev *pci;
333 int dev_index;
333 334
334 /* chip type specific */ 335 /* chip type specific */
335 int driver_type; 336 int driver_type;
@@ -1026,12 +1027,13 @@ static int setup_bdle(struct snd_pcm_substream *substream,
1026/* 1027/*
1027 * set up BDL entries 1028 * set up BDL entries
1028 */ 1029 */
1029static int azx_setup_periods(struct snd_pcm_substream *substream, 1030static int azx_setup_periods(struct azx *chip,
1031 struct snd_pcm_substream *substream,
1030 struct azx_dev *azx_dev) 1032 struct azx_dev *azx_dev)
1031{ 1033{
1032 u32 *bdl; 1034 u32 *bdl;
1033 int i, ofs, periods, period_bytes; 1035 int i, ofs, periods, period_bytes;
1034 int pos_adj = 0; 1036 int pos_adj;
1035 1037
1036 /* reset BDL address */ 1038 /* reset BDL address */
1037 azx_sd_writel(azx_dev, SD_BDLPL, 0); 1039 azx_sd_writel(azx_dev, SD_BDLPL, 0);
@@ -1046,15 +1048,16 @@ static int azx_setup_periods(struct snd_pcm_substream *substream,
1046 ofs = 0; 1048 ofs = 0;
1047 azx_dev->frags = 0; 1049 azx_dev->frags = 0;
1048 azx_dev->irq_ignore = 0; 1050 azx_dev->irq_ignore = 0;
1049 if (bdl_pos_adj > 0) { 1051 pos_adj = bdl_pos_adj[chip->dev_index];
1052 if (pos_adj > 0) {
1050 struct snd_pcm_runtime *runtime = substream->runtime; 1053 struct snd_pcm_runtime *runtime = substream->runtime;
1051 pos_adj = (bdl_pos_adj * runtime->rate + 47999) / 48000; 1054 pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
1052 if (!pos_adj) 1055 if (!pos_adj)
1053 pos_adj = 1; 1056 pos_adj = 1;
1054 pos_adj = frames_to_bytes(runtime, pos_adj); 1057 pos_adj = frames_to_bytes(runtime, pos_adj);
1055 if (pos_adj >= period_bytes) { 1058 if (pos_adj >= period_bytes) {
1056 snd_printk(KERN_WARNING "Too big adjustment %d\n", 1059 snd_printk(KERN_WARNING "Too big adjustment %d\n",
1057 bdl_pos_adj); 1060 bdl_pos_adj[chip->dev_index]);
1058 pos_adj = 0; 1061 pos_adj = 0;
1059 } else { 1062 } else {
1060 ofs = setup_bdle(substream, azx_dev, 1063 ofs = setup_bdle(substream, azx_dev,
@@ -1063,7 +1066,8 @@ static int azx_setup_periods(struct snd_pcm_substream *substream,
1063 goto error; 1066 goto error;
1064 azx_dev->irq_ignore = 1; 1067 azx_dev->irq_ignore = 1;
1065 } 1068 }
1066 } 1069 } else
1070 pos_adj = 0;
1067 for (i = 0; i < periods; i++) { 1071 for (i = 0; i < periods; i++) {
1068 if (i == periods - 1 && pos_adj) 1072 if (i == periods - 1 && pos_adj)
1069 ofs = setup_bdle(substream, azx_dev, &bdl, ofs, 1073 ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
@@ -1388,7 +1392,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1388 1392
1389 snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", 1393 snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
1390 azx_dev->bufsize, azx_dev->format_val); 1394 azx_dev->bufsize, azx_dev->format_val);
1391 if (azx_setup_periods(substream, azx_dev) < 0) 1395 if (azx_setup_periods(chip, substream, azx_dev) < 0)
1392 return -EINVAL; 1396 return -EINVAL;
1393 azx_setup_controller(chip, azx_dev); 1397 azx_setup_controller(chip, azx_dev);
1394 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -2001,6 +2005,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2001 chip->irq = -1; 2005 chip->irq = -1;
2002 chip->driver_type = driver_type; 2006 chip->driver_type = driver_type;
2003 chip->msi = enable_msi; 2007 chip->msi = enable_msi;
2008 chip->dev_index = dev;
2004 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); 2009 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
2005 2010
2006 chip->position_fix = check_position_fix(chip, position_fix[dev]); 2011 chip->position_fix = check_position_fix(chip, position_fix[dev]);