aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-18 13:22:33 -0400
committerTakashi Iwai <tiwai@suse.de>2012-03-18 13:22:33 -0400
commit44c76a960a62fcc46cbcaa0a22a34e666a729329 (patch)
treed3887c858f6adffb6714da3cdc0059f93588344c /sound/pci
parentdbf117cbb9c89991727d42e3161e68b868a1b6ae (diff)
parentc6b76d1f02e2ab1109d8549877a3a24c6a2b4587 (diff)
Merge branch 'topic/misc' into for-linus
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/au88x0/au88x0.h13
-rw-r--r--sound/pci/au88x0/au88x0_core.c20
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c127
-rw-r--r--sound/pci/ctxfi/ctvmem.c2
-rw-r--r--sound/pci/ice1712/ice1724.c23
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c9
6 files changed, 179 insertions, 15 deletions
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index bb938153a964..466a5c8e8354 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -26,7 +26,7 @@
26#include <sound/mpu401.h> 26#include <sound/mpu401.h>
27#include <sound/hwdep.h> 27#include <sound/hwdep.h>
28#include <sound/ac97_codec.h> 28#include <sound/ac97_codec.h>
29 29#include <sound/tlv.h>
30#endif 30#endif
31 31
32#ifndef CHIP_AU8820 32#ifndef CHIP_AU8820
@@ -107,6 +107,14 @@
107#define NR_WTPB 0x20 /* WT channels per each bank. */ 107#define NR_WTPB 0x20 /* WT channels per each bank. */
108#define NR_PCM 0x10 108#define NR_PCM 0x10
109 109
110struct pcm_vol {
111 struct snd_kcontrol *kctl;
112 int active;
113 int dma;
114 int mixin[4];
115 int vol[4];
116};
117
110/* Structs */ 118/* Structs */
111typedef struct { 119typedef struct {
112 //int this_08; /* Still unknown */ 120 //int this_08; /* Still unknown */
@@ -168,6 +176,7 @@ struct snd_vortex {
168 /* Xtalk canceler */ 176 /* Xtalk canceler */
169 int xt_mode; /* 1: speakers, 0:headphones. */ 177 int xt_mode; /* 1: speakers, 0:headphones. */
170#endif 178#endif
179 struct pcm_vol pcm_vol[NR_PCM];
171 180
172 int isquad; /* cache of extended ID codec flag. */ 181 int isquad; /* cache of extended ID codec flag. */
173 182
@@ -239,7 +248,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt);
239/* Connection stuff. */ 248/* Connection stuff. */
240static void vortex_connect_default(vortex_t * vortex, int en); 249static void vortex_connect_default(vortex_t * vortex, int en);
241static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, 250static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
242 int dir, int type); 251 int dir, int type, int subdev);
243static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, 252static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
244 int restype); 253 int restype);
245#ifndef CHIP_AU8810 254#ifndef CHIP_AU8810
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 6933a27a5d76..525f881f0409 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
2050} 2050}
2051 2051
2052/* Default Connections */ 2052/* Default Connections */
2053static int
2054vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
2055 2053
2056static void vortex_connect_default(vortex_t * vortex, int en) 2054static void vortex_connect_default(vortex_t * vortex, int en)
2057{ 2055{
@@ -2111,15 +2109,13 @@ static void vortex_connect_default(vortex_t * vortex, int en)
2111 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. 2109 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
2112*/ 2110*/
2113static int 2111static int
2114vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) 2112vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
2113 int type, int subdev)
2115{ 2114{
2116 stream_t *stream; 2115 stream_t *stream;
2117 int i, en; 2116 int i, en;
2117 struct pcm_vol *p;
2118 2118
2119 if ((nr_ch == 3)
2120 || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
2121 return -EBUSY;
2122
2123 if (dma >= 0) { 2119 if (dma >= 0) {
2124 en = 0; 2120 en = 0;
2125 vortex_adb_checkinout(vortex, 2121 vortex_adb_checkinout(vortex,
@@ -2250,6 +2246,14 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
2250 MIX_DEFIGAIN); 2246 MIX_DEFIGAIN);
2251#endif 2247#endif
2252 } 2248 }
2249 if (stream->type == VORTEX_PCM_ADB && en) {
2250 p = &vortex->pcm_vol[subdev];
2251 p->dma = dma;
2252 for (i = 0; i < nr_ch; i++)
2253 p->mixin[i] = mix[i];
2254 for (i = 0; i < ch_top; i++)
2255 p->vol[i] = 0;
2256 }
2253 } 2257 }
2254#ifndef CHIP_AU8820 2258#ifndef CHIP_AU8820
2255 else { 2259 else {
@@ -2473,7 +2477,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2473 hwread(vortex->mmio, VORTEX_IRQ_STAT); 2477 hwread(vortex->mmio, VORTEX_IRQ_STAT);
2474 handled = 1; 2478 handled = 1;
2475 } 2479 }
2476 if (source & IRQ_MIDI) { 2480 if ((source & IRQ_MIDI) && vortex->rmidi) {
2477 snd_mpu401_uart_interrupt(vortex->irq, 2481 snd_mpu401_uart_interrupt(vortex->irq,
2478 vortex->rmidi->private_data); 2482 vortex->rmidi->private_data);
2479 handled = 1; 2483 handled = 1;
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 0ef2f9712208..e59f120742a4 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -122,6 +122,18 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
122 .mask = 0, 122 .mask = 0,
123}; 123};
124#endif 124#endif
125
126static void vortex_notify_pcm_vol_change(struct snd_card *card,
127 struct snd_kcontrol *kctl, int activate)
128{
129 if (activate)
130 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
131 else
132 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
133 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
134 SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
135}
136
125/* open callback */ 137/* open callback */
126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) 138static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
127{ 139{
@@ -230,12 +242,14 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
230 if (stream != NULL) 242 if (stream != NULL)
231 vortex_adb_allocroute(chip, stream->dma, 243 vortex_adb_allocroute(chip, stream->dma,
232 stream->nr_ch, stream->dir, 244 stream->nr_ch, stream->dir,
233 stream->type); 245 stream->type,
246 substream->number);
234 /* Alloc routes. */ 247 /* Alloc routes. */
235 dma = 248 dma =
236 vortex_adb_allocroute(chip, -1, 249 vortex_adb_allocroute(chip, -1,
237 params_channels(hw_params), 250 params_channels(hw_params),
238 substream->stream, type); 251 substream->stream, type,
252 substream->number);
239 if (dma < 0) { 253 if (dma < 0) {
240 spin_unlock_irq(&chip->lock); 254 spin_unlock_irq(&chip->lock);
241 return dma; 255 return dma;
@@ -246,6 +260,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
246 vortex_adbdma_setbuffers(chip, dma, 260 vortex_adbdma_setbuffers(chip, dma,
247 params_period_bytes(hw_params), 261 params_period_bytes(hw_params),
248 params_periods(hw_params)); 262 params_periods(hw_params));
263 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
264 chip->pcm_vol[substream->number].active = 1;
265 vortex_notify_pcm_vol_change(chip->card,
266 chip->pcm_vol[substream->number].kctl, 1);
267 }
249 } 268 }
250#ifndef CHIP_AU8810 269#ifndef CHIP_AU8810
251 else { 270 else {
@@ -275,10 +294,18 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
275 spin_lock_irq(&chip->lock); 294 spin_lock_irq(&chip->lock);
276 // Delete audio routes. 295 // Delete audio routes.
277 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { 296 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
278 if (stream != NULL) 297 if (stream != NULL) {
298 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
299 chip->pcm_vol[substream->number].active = 0;
300 vortex_notify_pcm_vol_change(chip->card,
301 chip->pcm_vol[substream->number].kctl,
302 0);
303 }
279 vortex_adb_allocroute(chip, stream->dma, 304 vortex_adb_allocroute(chip, stream->dma,
280 stream->nr_ch, stream->dir, 305 stream->nr_ch, stream->dir,
281 stream->type); 306 stream->type,
307 substream->number);
308 }
282 } 309 }
283#ifndef CHIP_AU8810 310#ifndef CHIP_AU8810
284 else { 311 else {
@@ -506,6 +533,83 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
506 }, 533 },
507}; 534};
508 535
536/* subdevice PCM Volume control */
537
538static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
539 struct snd_ctl_elem_info *uinfo)
540{
541 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
542 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
543 uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
544 uinfo->value.integer.min = -128;
545 uinfo->value.integer.max = 32;
546 return 0;
547}
548
549static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol)
551{
552 int i;
553 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
554 int subdev = kcontrol->id.subdevice;
555 struct pcm_vol *p = &vortex->pcm_vol[subdev];
556 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
557 for (i = 0; i < max_chn; i++)
558 ucontrol->value.integer.value[i] = p->vol[i];
559 return 0;
560}
561
562static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 int i;
566 int changed = 0;
567 int mixin;
568 unsigned char vol;
569 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
570 int subdev = kcontrol->id.subdevice;
571 struct pcm_vol *p = &vortex->pcm_vol[subdev];
572 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
573 for (i = 0; i < max_chn; i++) {
574 if (p->vol[i] != ucontrol->value.integer.value[i]) {
575 p->vol[i] = ucontrol->value.integer.value[i];
576 if (p->active) {
577 switch (vortex->dma_adb[p->dma].nr_ch) {
578 case 1:
579 mixin = p->mixin[0];
580 break;
581 case 2:
582 default:
583 mixin = p->mixin[(i < 2) ? i : (i - 2)];
584 break;
585 case 4:
586 mixin = p->mixin[i];
587 break;
588 };
589 vol = p->vol[i];
590 vortex_mix_setinputvolumebyte(vortex,
591 vortex->mixplayb[i], mixin, vol);
592 }
593 changed = 1;
594 }
595 }
596 return changed;
597}
598
599static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
600
601static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
602 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
603 .name = "PCM Playback Volume",
604 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
605 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
606 SNDRV_CTL_ELEM_ACCESS_INACTIVE,
607 .info = snd_vortex_pcm_vol_info,
608 .get = snd_vortex_pcm_vol_get,
609 .put = snd_vortex_pcm_vol_put,
610 .tlv = { .p = vortex_pcm_vol_db_scale },
611};
612
509/* create a pcm device */ 613/* create a pcm device */
510static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) 614static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
511{ 615{
@@ -555,5 +659,20 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
555 return err; 659 return err;
556 } 660 }
557 } 661 }
662 if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
663 for (i = 0; i < NR_PCM; i++) {
664 chip->pcm_vol[i].active = 0;
665 chip->pcm_vol[i].dma = -1;
666 kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
667 if (!kctl)
668 return -ENOMEM;
669 chip->pcm_vol[i].kctl = kctl;
670 kctl->id.device = 0;
671 kctl->id.subdevice = i;
672 err = snd_ctl_add(chip->card, kctl);
673 if (err < 0)
674 return err;
675 }
676 }
558 return 0; 677 return 0;
559} 678}
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index b78f3fc3c33c..6109490b83e8 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -36,7 +36,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
36 36
37 size = CT_PAGE_ALIGN(size); 37 size = CT_PAGE_ALIGN(size);
38 if (size > vm->size) { 38 if (size > vm->size) {
39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " 39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual "
40 "memory space available!\n"); 40 "memory space available!\n");
41 return NULL; 41 return NULL;
42 } 42 }
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 92362973764d..812d10e43ae0 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1013,6 +1013,25 @@ static int set_rate_constraints(struct snd_ice1712 *ice,
1013 ice->hw_rates); 1013 ice->hw_rates);
1014} 1014}
1015 1015
1016/* if the card has the internal rate locked (is_pro_locked), limit runtime
1017 hw rates to the current internal rate only.
1018*/
1019static void constrain_rate_if_locked(struct snd_pcm_substream *substream)
1020{
1021 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
1022 struct snd_pcm_runtime *runtime = substream->runtime;
1023 unsigned int rate;
1024 if (is_pro_rate_locked(ice)) {
1025 rate = ice->get_rate(ice);
1026 if (rate >= runtime->hw.rate_min
1027 && rate <= runtime->hw.rate_max) {
1028 runtime->hw.rate_min = rate;
1029 runtime->hw.rate_max = rate;
1030 }
1031 }
1032}
1033
1034
1016/* multi-channel playback needs alignment 8x32bit regardless of the channels 1035/* multi-channel playback needs alignment 8x32bit regardless of the channels
1017 * actually used 1036 * actually used
1018 */ 1037 */
@@ -1046,6 +1065,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
1046 VT1724_BUFFER_ALIGN); 1065 VT1724_BUFFER_ALIGN);
1047 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1066 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1048 VT1724_BUFFER_ALIGN); 1067 VT1724_BUFFER_ALIGN);
1068 constrain_rate_if_locked(substream);
1049 if (ice->pro_open) 1069 if (ice->pro_open)
1050 ice->pro_open(ice, substream); 1070 ice->pro_open(ice, substream);
1051 return 0; 1071 return 0;
@@ -1066,6 +1086,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
1066 VT1724_BUFFER_ALIGN); 1086 VT1724_BUFFER_ALIGN);
1067 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1087 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1068 VT1724_BUFFER_ALIGN); 1088 VT1724_BUFFER_ALIGN);
1089 constrain_rate_if_locked(substream);
1069 if (ice->pro_open) 1090 if (ice->pro_open)
1070 ice->pro_open(ice, substream); 1091 ice->pro_open(ice, substream);
1071 return 0; 1092 return 0;
@@ -1215,6 +1236,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
1215 VT1724_BUFFER_ALIGN); 1236 VT1724_BUFFER_ALIGN);
1216 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1237 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1217 VT1724_BUFFER_ALIGN); 1238 VT1724_BUFFER_ALIGN);
1239 constrain_rate_if_locked(substream);
1218 if (ice->spdif.ops.open) 1240 if (ice->spdif.ops.open)
1219 ice->spdif.ops.open(ice, substream); 1241 ice->spdif.ops.open(ice, substream);
1220 return 0; 1242 return 0;
@@ -1251,6 +1273,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
1251 VT1724_BUFFER_ALIGN); 1273 VT1724_BUFFER_ALIGN);
1252 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1274 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1253 VT1724_BUFFER_ALIGN); 1275 VT1724_BUFFER_ALIGN);
1276 constrain_rate_if_locked(substream);
1254 if (ice->spdif.ops.open) 1277 if (ice->spdif.ops.open)
1255 ice->spdif.ops.open(ice, substream); 1278 ice->spdif.ops.open(ice, substream);
1256 return 0; 1279 return 0;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 12a9a2b03387..a8159b81e9c4 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2317,6 +2317,10 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) 2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); 2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); 2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2320 pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,
2321 &chip->saved_dsxg_legacy);
2322 pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2323 &chip->saved_dsxg_elegacy);
2320 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); 2324 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2321 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); 2325 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
2322 snd_ymfpci_disable_dsp(chip); 2326 snd_ymfpci_disable_dsp(chip);
@@ -2351,6 +2355,11 @@ int snd_ymfpci_resume(struct pci_dev *pci)
2351 2355
2352 snd_ac97_resume(chip->ac97); 2356 snd_ac97_resume(chip->ac97);
2353 2357
2358 pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,
2359 chip->saved_dsxg_legacy);
2360 pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2361 chip->saved_dsxg_elegacy);
2362
2354 /* start hw again */ 2363 /* start hw again */
2355 if (chip->start_count > 0) { 2364 if (chip->start_count > 0) {
2356 spin_lock_irq(&chip->reg_lock); 2365 spin_lock_irq(&chip->reg_lock);