diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 25 |
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; | |||
55 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 55 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
56 | static char *model[SNDRV_CARDS]; | 56 | static char *model[SNDRV_CARDS]; |
57 | static int position_fix[SNDRV_CARDS]; | 57 | static int position_fix[SNDRV_CARDS]; |
58 | static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; | ||
58 | static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; | 59 | static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; |
59 | static int single_cmd; | 60 | static int single_cmd; |
60 | static int enable_msi; | 61 | static int enable_msi; |
61 | static int bdl_pos_adj = 1; | ||
62 | 62 | ||
63 | module_param_array(index, int, NULL, 0444); | 63 | module_param_array(index, int, NULL, 0444); |
64 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 64 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
@@ -71,6 +71,8 @@ MODULE_PARM_DESC(model, "Use the given board model."); | |||
71 | module_param_array(position_fix, int, NULL, 0444); | 71 | module_param_array(position_fix, int, NULL, 0444); |
72 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer " | 72 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer " |
73 | "(0 = auto, 1 = none, 2 = POSBUF)."); | 73 | "(0 = auto, 1 = none, 2 = POSBUF)."); |
74 | module_param_array(bdl_pos_adj, int, NULL, 0644); | ||
75 | MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); | ||
74 | module_param_array(probe_mask, int, NULL, 0444); | 76 | module_param_array(probe_mask, int, NULL, 0444); |
75 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); | 77 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); |
76 | module_param(single_cmd, bool, 0444); | 78 | module_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)."); |
79 | module_param(enable_msi, int, 0444); | 81 | module_param(enable_msi, int, 0444); |
80 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); | 82 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); |
81 | module_param(bdl_pos_adj, int, 0644); | ||
82 | MODULE_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 { | |||
330 | struct azx { | 330 | struct 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 | */ |
1029 | static int azx_setup_periods(struct snd_pcm_substream *substream, | 1030 | static 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]); |